Envíe su primer trabajo multimedia en minutos.
Proporciona a MediaRuntime una URL de medios accesible, solicita exactamente las salidas que necesitas y recibe un webhook terminal firmado. Usa el endpoint de carga opcional solo cuando todavía no tengas una URL de origen.
Cree el trabajo, espere y descargue el paquete ZIP.
El CLI acepta rutas de archivos locales relativas o absolutas y sube los bytes automáticamente. MediaRuntime también acepta directamente una URL HTTP(S) pública o una URL de lectura firmada y temporal. Para la primera ejecución, usa la opción --download del CLI o el helper job.wait() de un SDK para recibir el paquete ZIP canónico. En producción, conserva job_id y procesa el webhook firmado de la cuenta en lugar de consultar repetidamente.
# 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"]
}'Clona un inicio rápido completo
Proyectos ejecutables con los SDK de Node.js y Python, ejemplos HTTP en Go y PHP, receptores de webhooks firmados y una guía de Postman viven juntos en un repositorio público.
# 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"
}Ejecuta e inspecciona trabajos multimedia desde tu terminal.
El CLI oficial es la vía más rápida para procesar archivos locales, diagnosticar producción, descargar paquetes y probar un receptor webhook local. El CLI y los SDK de Node y Python son paquetes 1.x estables cuyas interfaces documentadas siguen el versionado semántico. Usan el mismo contrato público de trabajos y mantienen el paquete ZIP como resultado canónico.
npm install --global @mediaruntime/cli
mediaruntime login
mediaruntime jobs list --limit 3Enviar un archivo local y descargar el paquete completo
Pasa una ruta relativa como ./launch.mp4 o una ruta local absoluta; el CLI la sube automáticamente antes de crear el trabajo. En una terminal interactiva, un indicador muestra las fases de carga, espera y descarga verificada. --download espera el resultado terminal y publica el ZIP canónico de forma atómica. Los archivos existentes se conservan salvo que se indique --force.
# 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.zipDescubrir el catálogo público en vivo
mediaruntime capabilities resume los alias y las funciones, mientras que mediaruntime presets list devuelve el catálogo público ordenado de presets. Estos comandos de solo lectura no requieren inicio de sesión en el navegador 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 --jsonEjecutar presets públicos exactos
Usa --preset de forma repetida para entradas exactas del catálogo, como DASH o VP9. El CLI valida cada nombre con el catálogo público en vivo antes de crear el trabajo; los alias y los presets exactos se pueden combinar en el orden solicitado.
# 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.zipInspeccionar y recuperar trabajos
Lista una página de trabajos de la cuenta, filtra por estado, inspecciona un trabajo o descarga su paquete ZIP retenido. Usa el cursor opaco que imprime jobs list para solicitar la página siguiente.
mediaruntime jobs list --status COMPLETED --limit 20
mediaruntime jobs get job_123
mediaruntime jobs get job_123 --download ./job_123.zipUsar claves API para automatización
CI, servidores y contenedores deben inyectar MEDIARUNTIME_API_KEY desde un gestor de secretos. No incluyas credenciales en argumentos de comandos, control de código fuente, registros ni archivos de configuración de texto plano.
# Permanently supported for CI, servers, and containers.
export MEDIARUNTIME_API_KEY="sk_..."
mediaruntime jobs list --limit 3| Capacidad | Contrato del comando | Notas |
|---|---|---|
| Alias de salida | --output video.web | Se aceptan los seis alias fijos; repite --output para solicitar varios entregables. |
| Salida para máquinas | --json | Escribe un único resultado JSON compacto y sin URL firmadas para scripts y CI. |
| Reintentos seguros | --idempotency-key | Reutiliza una clave de negocio para el mismo trabajo lógico incluso después de reiniciar el proceso. |
| Seguridad del paquete | --download / --force | Descarga solo paquetes terminales, verifica la integridad anunciada y evita sobrescrituras accidentales. |
| Estado de salida | 0–9, 130 | La autenticación, el rechazo de API, el fallo terminal, el tiempo de espera, el trigger y el paquete usan códigos distintos de cero. |
export MEDIARUNTIME_WEBHOOK_SECRET="whsec_..."
mediaruntime trigger job.completed \
--to http://127.0.0.1:3000/webhooks/mediaruntimeMantenga las claves API en su servidor.
Cree una clave desde Cuenta → Configuración para desarrolladores → Claves API. La clave sin formato se muestra una vez y pertenece a su administrador secreto, nunca al código del navegador, archivos binarios móviles, registros o control de fuente.
encabezado
Envíe X-API-Key en cada solicitud de /v1.
Almacenamiento
Almacene MEDIARUNTIME_API_KEY en un administrador secreto del lado del servidor.
Rotación
Cree un reemplazo, impleméntelo, verifique el tráfico y luego revoque la clave anterior.
npm install --global @mediaruntime/cli
mediaruntime login
mediaruntime jobs list --limit 3Haz que los metadatos resuelvan la integración.
El patrón de producción usado por wMedia es deliberadamente sencillo: envía una entrada, recetas de salida y suficientes metadatos opacos para relacionar el evento terminal con tu propio registro de base de datos.
{
"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 }
]
}
]
}| campo | Tipo | Notas |
|---|---|---|
| source | cadena u objeto | Entrada única canónica: una URL HTTP(S) pública, HTTP(S) firmada y temporal, gs:// accesible, o un objeto que solo contenga url. |
| file_url | cadena | Forma heredada y permanentemente compatible del source escalar. No combine source y file_url. |
| inputs | matriz | Distribución por lotes para 1–25 entradas. Cada elemento usa el source canónico; el file_url heredado sigue siendo compatible por elemento. No combine inputs con ninguno de los campos de entrada única. |
| outputs | matriz | 1 a 10 recetas de salida. Cada uno requiere tipo; Se recomienda encarecidamente preajuste. |
| metadata | objeto | Hasta 32 KiB de JSON. Persistió y se hizo eco en meta.request_metadata. |
| moderation | objeto | Premium visual-media comprobaciones: sexual, violencia, peligrosa. |
| watermark | objeto | Superposición de medios visuales Premium. La cuenta ya debe tener un logotipo PNG. |
Distribución por lotes
Utilice un lote cuando cada entrada necesite el mismo salidas. El metadatos por entrada se fusiona en cada trabajo secundario; el trabajo principal se convierte en su referencia de lote.
{
"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" }]
}Reintentos seguros con Idempotency-Key
Una solicitud con tiempo de espera agotado es ambigua: es posible que el trabajo haya estado en cola y solo se haya perdido la respuesta. Envíe un encabezado Idempotency-Key y volver a intentarlo es seguro: la misma clave devuelve el trabajo original en lugar de hacer cola y cobrar por un segundo. Sin el encabezado, el comportamiento no cambia y cada POST crea un nuevo trabajo.
# 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.Reglas clave
- Un UUID funciona; una identificación determinista como
asset_0426:mp4_720p:v1es mejor, porque puedes regenerarla después de un fallo. - Las claves se asignan a su cuenta y se respetan durante 24 horas.
- Reutilizar una clave con un cuerpo diferente devuelve 422, generalmente una clave reutilizada en un bucle.
- Un reintento enviado mientras el primero todavía está ejecutándose devuelve 409; Vuelva a intentarlo después de un breve retroceso.
- ¿Enviar el mismo archivo dos veces a propósito? Utilice dos claves diferentes.
Elija el artefacto que desea que produzca el motor.
Empiece con un alias de salida fijo para los trabajos comunes. Use un `type` y un `preset` explícitos cuando necesite personalizar la receta; las combinaciones incompatibles pueden rechazarse o dirigirse de forma incorrecta.
Alias de salida fijos
Los alias son contratos estables del gateway. Se resuelven antes de la validación, la estimación, la facturación y la persistencia, y pueden combinarse con objetos de salida explícitos en el mismo array outputs.
| Alias | Se resuelve como | Artefactos | Nivel |
|---|---|---|---|
| video.web | mp4 / mp4_720p_h264_aac, JPG poster at 2s | MP4 H.264/AAC de 720p y póster JPG | Standard |
| video.streaming | hls / hls_ladder_v1 | Manifiesto HLS, variantes 1080p/720p y segmentos | Standard |
| video.social | social / social_vertical_blur | MP4 de 1080×1920 con relleno 9:16 desenfocado | Premium |
| audio.web | audio / audio_aac_128k | AAC/M4A de 128 kbps | Standard |
| audio.transcription | audio / audio_aac_128k with base subtitles | AAC/M4A más subtítulos SRT y WebVTT | Standard |
| image.web | image / image_multi_v1 with two WebP renditions | Variantes WebP de 1200×630 y 320×320 | Premium |
{
"source": "https://cdn.example.com/landscape-interview.mp4",
"outputs": ["video.social"]
}social_vertical_blur crea un H.264/AAC MP4 de 1080 × 1920. La fuente se escala para ajustarse sin recortar; una copia borrosa llena el lienzo 9:16 detrás de ella. Úselo para Reels, TikTok y Shorts. Es una receta Premium porque la salida vertical tiene 1920 píxeles de alto.Archivos de vídeo y carteles.
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| video_clip_v1 (type: mp4) | Vídeo | Renderiza un intervalo preciso como MP4 H.264/AAC, con encuadre original o vertical desenfocado y subtítulos suministrados opcionales. Standard, sin repetir la transcripción. clip.mp4, clip.srt and clip.vtt when transcript is supplied. | Standard |
| mp4_720p_h264_aac (type: mp4) | Vídeo | 720p H.264/AAC MP4 con inicio rápido para reproducción web. MP4 video. | Standard |
| mp4_ladder_v1 (type: mp4) | Vídeo | Tres interpretaciones de MP4 a 1080p, 720p y 480p, además de un póster para cada interpretación. 1080p MP4, 720p MP4, 480p MP4. | Standard |
| transmux_mp4_fast (type: mp4) | Vídeo | Copia transmisiones existentes en un inicio rápido MP4 sin volver a codificar. Si la copia falla y el respaldo está habilitado, el motor vuelve a codificar con 720p H.264 preajuste. MP4 video. | Standard |
| poster_frame_v1 (type: mp4) | Vídeo | Un JPG de 720p capturado en poster_time_sec. La solicitud tipo sigue siendo mp4. JPG poster. | Standard |
| mp4_hevc_1080p (type: mp4) | Vídeo | 1080p HEVC/H.265 + AAC MP4 con la etiqueta hvc1 para reproducción de Apple. HEVC MP4. | Premium |
| mp4_av1_smart (type: mp4) | Vídeo | 1080p AV1 + Opus MP4 optimizado para eficiencia de compresión; La codificación requiere un uso intensivo de la CPU. AV1 MP4. | Premium |
| mov_prores_422 (type: mp4) | Vídeo | ProRes 422 HQ + PCM MOV maestro de edición. Conserva las dimensiones de origen y produce un archivo intermedio de gran tamaño. ProRes MOV. | Premium |
Vídeo social
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| audiogram_v1 (type: social) | Audio o vídeo con audio. | Compone audio con ilustración ajustada, una forma de onda de alto contraste y subtítulos opcionales en una zona segura en un MP4 social H.264/AAC Premium con póster limpio. H.264/AAC audiogram MP4, caption-free poster JPEG, audiogram.json, audiogram.waveform.json. | Premium |
| social_vertical_blur (type: social) | Vídeo | 1080×1920 H.264/AAC MP4. Ajusta la fuente sobre un fondo borroso de 9:16 para carretes, TikTok y cortos. vertical MP4. | Premium |
Animado GIF
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| gif_hq (type: gif) | Imagen o vídeo | GIF animado a 480 px de ancho y 15 fps usando generación de paleta para una mejor calidad de color. animated GIF. | Standard |
Extracción de cuadros
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| clip_candidates_v1 (type: frames) | Audio o vídeo con audio. | Sugiere clips usando Whisper existente o una transcripción suministrada, límites del habla y palabras clave. Análisis Premium; la puntuación no predice viralidad. clip_candidates.json with candidates and reusable source-timed transcript. | Premium |
| contact_sheet_v1 (type: frames) | Vídeo | Crea hojas de contacto numeradas y contact_sheet.json, que relaciona cada mosaico con su marca de tiempo de origen. numbered contact-sheet images, contact_sheet.json. | Standard |
| extract_frames_1 (type: frames) | Vídeo | Secuencia de cuadros numerada JPG muestreada a 1 cuadro por segundo. JPG frames at 1 fps. | Standard |
| extract_frames_5 (type: frames) | Vídeo | Secuencia de cuadros numerada JPG muestreada a 5 cuadros por segundo. JPG frames at 5 fps. | Standard |
| scene_detect_v1 (type: frames) | Vídeo | Detecta límites de planos y exporta un fotograma clave JPG por plano, además de un índice scenes.txt con marcas de tiempo y puntuaciones. scene JPGs, scene timeline. | Standard |
| perceptual_hash_v1 (type: frames) | Vídeo | Muestrea el vídeo y escribe huellas perceptuales de 64 bits en phash.json para detectar recargas y duplicados similares. phash.json. | Standard |
Transmisión
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| hls_ladder_v1 (type: hls) | Vídeo | Paquete HLS VOD con variantes H.264/AAC de 1080p y 720p, lista de reproducción maestra y segmentos de 6 segundos. HLS master playlist, variant playlists, media segments. | Standard |
| transmux_hls_fast (type: hls) | Vídeo | Copia flujos compatibles a un paquete HLS sin recodificar. Con el respaldo activado, los flujos incompatibles se codifican con hls_ladder_v1. HLS master playlist, variant playlist, media segments. | Standard |
Transmisión MPEG-DASH
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| dash_ladder_v1 (type: dash) | Vídeo | Paquete MPEG-DASH con representaciones H.264/AAC de 1080p y 720p, manifest.mpd canónico y segmentos MP4 fragmentados. DASH MPD, initialization segments, media segments. | Standard |
| transmux_dash_fast (type: dash) | Vídeo | Copia flujos compatibles a MPEG-DASH sin recodificar. Con el respaldo activado, los flujos incompatibles se codifican con dash_ladder_v1. DASH MPD, initialization segments, media segments. | Standard |
Vídeo WebM
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| webm_vp9_1080p (type: webm) | Vídeo | WebM VP9 + Opus a 1080p para navegadores modernos. Es una codificación VP9 real, no una etiqueta MP4. VP9 WebM. | Premium |
Audio
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| audio_copy_fast (type: audio) | Audio o vídeo con audio. | Copia la secuencia de audio de origen sin volver a codificarla. Si la copia falla y el respaldo está habilitado, el motor escribe AAC de 128 kbps en su lugar. audio file. | Standard |
| audio_aac_128k (type: audio) | Audio o vídeo con audio. | 128 kbps AAC en un archivo M4A de inicio rápido. M4A audio. | Standard |
| audio_mp3_128k (type: audio) | Audio o vídeo con audio. | Archivo MP3 de 128 kbps. MP3 audio. | Standard |
| audio_opus_96k (type: audio) | Audio o vídeo con audio. | Archivo Opus de 96 kbps, muy adecuado para la transmisión de voz. Opus audio. | Standard |
| audio_loudnorm_aac_128k (type: audio) | Audio o vídeo con audio. | Se normaliza hacia -16 LUFS, luego escribe 128 kbps AAC. normalized M4A audio, loudness metrics. | Standard |
| audio_trim_silence_aac_128k (type: audio) | Audio o vídeo con audio. | Elimina el silencio inicial y final y luego escribe AAC a 128 kbps. trimmed M4A audio. | Premium |
| audio_loudnorm_trim_aac_128k (type: audio) | Audio o vídeo con audio. | Recorta el silencio de límites, se normaliza hacia -16 LUFS y luego escribe 128 kbps AAC. trimmed and normalized M4A audio, loudness metrics. | Premium |
| audio_whisper_prep (type: audio) | Audio o vídeo con audio. | PCM mono de 16 kHz WAV preparado para Whisper, ASR u otros canales de voz. WAV audio. | Standard |
Derivados de imagen
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| image_multi_v1 (type: image) | Imagen o vídeo | Crea las imágenes solicitadas con fit, fill, cover o contain. Las rendiciones JPG y WebP pueden usar max_bytes como límite estricto verificado y reciben image_size_limits.json. El nivel depende del formato, tamaño, cantidad, recorte inteligente y eliminación de fondo. image renditions, image_size_limits.json when max_bytes is used, smart_crop.json when enabled. | Standard |
| image_animated_webp_v1 (type: image) | Vídeo | Crea un WebP animado limitado desde vídeo con anchura, FPS, inicio, duración, calidad y repeticiones configurables. animated WebP. | Premium |
| image_animated_apng_v1 (type: image) | Vídeo | Crea un PNG animado sin pérdida desde vídeo con anchura, FPS, inicio, duración y repeticiones configurables. animated PNG. | Premium |
| image_placeholders_v1 (type: image) | Imagen o vídeo | Crea BlurHash y ThumbHash compatibles, geometría de origen y marcador, un color dominante con alfa y un LQIP WebP con límite de bytes desde una imagen o fotograma de vídeo. placeholders.json, lqip.webp. | Standard |
Análisis e informes
| Preestablecido | enviar | Ejecución del trabajo | Nivel básico |
|---|---|---|---|
| compatibility_report_v1 (type: image) | Vídeo | Evalúa el vídeo con cinco perfiles versionados para web, móvil, carga social y edición, con evidencia por regla y presets correctivos. compatibility_report.json. | Standard |
| media_report_v1 (type: image) | Audio, imagen o vídeo | Inspecciona metadatos de audio, vídeo o imagen sin transcodificar y escribe media_report.json con detalles del contenedor y los flujos, además de GOP, EXIF y GPS cuando estén presentes. media_report.json. | Standard |
| code_detect_v1 (type: frames) | Imagen o vídeo | Escanea una ventana inicial limitada para detectar códigos QR y de barras en imágenes, vídeo, animaciones y carátulas incrustadas en audio; genera codes.json y fotogramas de evidencia cuando encuentra códigos. codes.json, evidence frames when codes are found. | Standard |
transmux_*_fast evitan una codificación que cambie la calidad cuando los flujos son compatibles con MP4, HLS o DASH. Si la copia falla y el respaldo está activado, el motor usa el preset codificado correspondiente.Utilice una fuente. Produzca los formatos y artefactos sidecar que su producto necesita.
La extensión de origen no selecciona la salida. tipo y preajuste eligen la receta ejecutable, por lo que un video cargado puede convertirse en video de reproducción, medios de solo audio, transcripciones, vistas previas de GIF, carteles o secuencias de fotogramas en el mismo trabajo asincrónico.
| Fuente | Entregable | Receta |
|---|---|---|
| JPG, PNG o WebP | JPG, PNG, WebP o derivados AVIF | imagen + image_multi_v1; elija images[].format, dimensiones, mode y quality. JPG/WebP admite max_bytes y min_quality para un límite estricto verificado. |
| Vídeo | Web MP4, HLS, video social o edición maestra | Elija el mp4, hls o social preajuste correspondiente. |
| Vídeo | Secuencia de fotograma animada GIF, póster o JPG | Utilice gif_hq, poster_frame_v1, extract_frames_1/5 o conecte gif_preview a una salida de vídeo. |
| Vídeo o audio | M4A, MP3, Opus o voz WAV | Elija el audio correspondiente_* preajuste; video entradas se extrae su transmisión de audio. |
| Discurso en vídeo o audio | SRT, WebVTT o ambos | Agregue subtítulos a una salida de audio o video y elija srt, vtt o ambos. |
{
"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 crea una lista de reproducción maestra, listas de reproducción variantes de 1080p y 720p H.264/AAC y segmentos multimedia de 6 segundos. Utilice la lista de reproducción maestra informada URL o junte el paquete completo.gif_hq crea un GIF primario completo de 480 px y 15 fps. gif_preview agrega un GIF más corto y cronometrado explícitamente a otra salida de video. Los ajustes preestablecidos de fotogramas devuelven secuencias JPG numeradas a uno o cinco fotogramas por segundo.Interruptores útiles
audio_aac_128k devuelve M4A, audio_mp3_128k devuelve MP3, audio_opus_96k devuelve Opus y audio_whisper_prep devuelve WAV mono de 16 kHz. Establezca subtitles.format en srt, vtt o both. Para una sola imagen de póster, envíe type: mp4 con preset: poster_frame_v1 y el poster_time_sec deseado.
Analizar, revisar y renderizar clips
Usa video_clip_v1 para un intervalo preciso o clip_candidates_v1 para sugerir fragmentos. Ambos usan la API de trabajos asíncronos.
El recorte manual no necesita un modelo
video_clip_v1 usa type: mp4 y procesamiento Standard. El inicio debe ser finito y ≥ 0; la duración, 0.1–300 segundos, completamente dentro del origen. original conserva la proporción hasta 1920 px en el lado largo y 30 fps; vertical_blur usa 720 × 1280 hasta 30 fps. El renderizado, incluso con subtítulos proporcionados, nunca ejecuta 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
}
}]
}Análisis opcional de candidatos
clip_candidates_v1 usa type: frames y Premium, incluso con texto proporcionado. Si clip_analysis.transcript falta o está vacío, se ejecuta Whisper; una transcripción no vacía lo omite. Subir texto es opcional. Duraciones mínima/máxima: 1–300 segundos; max_candidates: 1–20. El mínimo no puede superar el máximo ni la duración exacta del origen. Solo un análisis por trabajo; origen de hasta seis horas. Las puntuaciones reflejan límites del habla y palabras clave, no viralidad.
{
"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"]
}
}]
}Revisa antes de renderizar
Después de COMPLETED, GET /v1/jobs/{job_id}/clip-candidates devuelve la transcripción y los intervalos editables. El análisis produce clip_candidates.json, no vídeo ni JavaScript. Envía los intervalos como un nuevo trabajo video_clip_v1 con el mismo origen. candidates vacío es válido: empty_reason puede ser no_speech, no_keyword_match, no_matching_ranges o source_too_short (reservado para lectores de informes). Con candidatos es null; los informes antiguos pueden omitirlo. Una transcripción no vacía puede reutilizarse aunque no haya sugerencias.
Adjuntar e incrustar subtítulos con tiempos del origen
REST/Python usa clip.transcript con {start_time_sec, end_time_sec, text}; Node SDK usa {startTimeSec, endTimeSec, text}. Envía arrays de segmentos, no URL de archivos. Conserva los tiempos del origen completo; el motor recorta y reajusta los segmentos. burn_captions: true requiere texto que se solape con el clip. Studio acepta SRT, VTT o JSON (≤ 1 MiB) mediante archivo o nube; la selección en la lista lo adjunta inmediatamente. Una transcripción válida superpuesta habilita la casilla. Sandbox anónimo admite archivos locales; la nube exige iniciar sesión. Adjuntar texto al análisis está bajo la opción de reutilizar una transcripción. El ZIP incluye MP4, póster y los SRT/VTT superpuestos.
{
"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."}
]
}
}]
}Límites y disponibilidad
Transcripciones: ≤ 2,000 segmentos, ≤ 2,000 bytes UTF-8 por segmento y ≤ 256 KiB de texto; inicios finitos ordenados, fin > inicio, dentro del origen. Palabras clave: ≤ 20, ≤ 100 bytes UTF-8 cada una. Controles combinados: ≤ 512 KiB. El renderizado rechaza subtitles, watermark y ajustes independientes no relacionados. La estimación aceptada determina el nivel final. Sandbox público admite muestras configuradas y Standard; el análisis Premium requiere acceso apto a Workspace.
Preparación de SDK y CLI 1.4.0
Estos ejemplos requieren publicar e instalar los paquetes 1.4.0 correspondientes; la publicación sigue pendiente. Node ofrece jobs.getClipCandidates() y emptyReason; Python, jobs.get_clip_candidates() y empty_reason. La CLI acepta SRT, VTT y JSON locales con --clip-transcript (≤ 1 MiB). Un recorte manual sin ese indicador ni --clip-captions no necesita transcripción.
# 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.Comience con un preajuste; anular sólo lo que importa.
Los ajustes preestablecidos mantienen las solicitudes legibles y le dan al motor una base estable. Agregue opciones explícitas de reproducción, subtítulos, vista previa, códec o velocidad de bits solo cuando el producto las requiera.
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 resuelve el logotipo propiedad del servidor.Versiona la política completa, no copias del JSON de solicitud.
Las recetas alojadas son versiones inmutables y propias de la cuenta para outputs, moderation y watermark. Usa el nombre para la última versión activa o `name@version` cuando un despliegue no deba cambiar.
# 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 y SHA-256.web-video@1, social-video@1 y ai-transcription@1.Agregue análisis de seguridad visual en capas al trabajo.
La moderación usa un canal en capas para una imagen o un vídeo. El modo report devuelve evidencia y continúa el procesamiento. El modo block es una puerta fail-closed previa al motor: los veredictos block o review rechazan el trabajo y allow continúa.
{
"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 }
}
}| Contrato | Valor | Notas |
|---|---|---|
| Planificar | Premium | El API devuelve 403 a menos que la cuenta sea Premium o se permita la actualización automática. |
| Modo | report o block | report es observacional; block rechaza los veredictos block/review antes de iniciar el motor. |
| cheques | sexual, violencia, peligroso | Envíe de uno a tres comprobaciones. Al omitir comprobaciones se seleccionan los tres. |
| Entradas | Una imagen o video | Se rechazan las entradas solo de audio, los lotes y la moderación en Sandbox. |
| Muestreo de vídeo | Intervalo fijo, fotogramas acotados. | El servicio elige el intervalo y el límite; lea los valores reales de result.video y result.evidence. |
| decisión | permitir, revisar o bloquear la señal | report nunca bloquea la ejecución. block es fail-closed: allow continúa; review o block termina como REJECTED. |
| artefacto | meta/moderation_result.json | Incluido en el ZIP de salida y expuesto a través de meta.moderation_result.url cuando esté disponible. |
| Facturación | Por fotograma analizado | Una inferencia por cuadro: una imagen tiene 1 cuadro, un video se muestra hasta un límite de 24. Resuelto desde result.evidence.frames_sampled en use.breakdown.moderation_units. |
| Independiente | salidas puede estar vacío | Envía `outputs: []` para moderar un archivo sin transcodificarlo. Se factura únicamente la moderación. |
report cuando su aplicación tome la decisión de publicación. Use block para rechazar antes de transcodificar; un trabajo rechazado no tiene bundle de salida y factura solo unidades de moderación.Verifique los bytes sin procesar antes de confiar en el evento.
Los eventos terminales se entregan al menos una vez y no se garantiza el pedido. Verifique HMAC-SHA256, rechace marcas de tiempo obsoletas, deduplica event_id, reconozca rápidamente y mueva el trabajo pesado a una cola.
{
"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 o busque meta.engine_result_url para enumerar salidas individuales y rutas de artefactos.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);
}),
);Reglas de entrega
- Devuelva cualquier 2xx solo después de la verificación de la firma y la puesta en cola/deduplicación duradera.
- Trate a event_id como la clave de idempotencia.
- Utilice meta.request_metadata para encontrar su entidad sin una segunda tabla de búsqueda.
- Descargue el salidas retenido antes de la entrega.expiresAt.
- Un evento FAILED o REJECTED tiene error.code/message y no tiene ningún paquete utilizable. Un lote PARTIAL tiene error.code BATCH_PARTIAL; revise delivery.items para ver el estado de cada trabajo secundario y los bundles correctos.
Encuesta cuando un webhook no es práctico.
El envío regresa inmediatamente con un job_id. Los webhooks siguen siendo la forma de latencia más baja para saber si un trabajo ha terminado, pero las encuestas están disponibles para el desarrollo local, entornos sin un punto final público, conciliación y preguntas de soporte.
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 es el nivel de la clave API que envió el trabajo. required es lo que realmente necesita el trabajo, effective es el carril por el que corrió y billed es lo que le cobraron. Una clave premium que ejecuta un trabajo estándar muestra requested: premium con billed: standard: se le cobra por el trabajo, no por la clave.media informa lo que MediaRuntime encontró en su entrada cuando la probó en el momento del envío, la misma sonda que decide si se acepta un trabajo. Cuando un trabajo es RECHAZADO por un emparejamiento incompatible, esto explica por qué: un MP3 enviado a una salida de imagen muestra streams.video: 0, y un todavía enviado a una salida de fotogramas no tiene duration_sec. Nota video.width/height son dimensiones de PANTALLA con rotación aplicada, por lo que un clip de teléfono vertical lee 1080x1920 aunque encoded_width/encoded_height sean 1920x1080. Cada campo es opcional: si falta uno significa que la sonda no lo informó, nunca cero.GET /v1/jobs/{job_id}/moderation devuelve solo el veredicto, por lo que un cliente que consulta para decidir no descarga en cada petición los detalles de facturación y del paquete. Responde con verdict, decision y confidence por comprobación, además de likelihoods de escalado. Una comprobación marcada como review_only es consultiva: puede producir un veredicto review, pero no puede bloquear por sí sola. El endpoint devuelve **404 cuando el trabajo existe pero nunca se solicitó moderación**; una respuesta correcta vacía sería indistinguible de «moderado sin hallazgos». Los umbrales de cada decisión no se publican.GET /v1/jobs/{job_id}/media-report devuelve el documento media_report_v1 sin descargar el paquete. report lo lleva en línea; un informe inusualmente grande no se almacena en línea y la respuesta establece report en nulo con un download_url que aún se resuelve, así que maneje ambos. Devuelve 404 cuando el trabajo no incluye ningún informe.GET /v1/jobs/{job_id}/compatibility-report devuelve el documento versionado compatibility_report_v1 sin descargar el ZIP. Incluye cinco perfiles conservadores, evidencia por regla y un preset correctivo para perfiles incompatibles. Es una guía práctica, no una certificación exhaustiva de dispositivos. Maneje report o download_url; devuelve 404 si no se solicitó el preset.GET /v1/jobs/{job_id}/codes devuelve el escaneo limitado de code_detect_v1 sin descargar el ZIP. Admite imágenes, vídeo, animaciones y audio con carátula incrustada; el audio sin imagen se rechaza con una explicación. Conserva como máximo 12 fotogramas muestreados y 16 códigos únicos por fotograma. Trate cada decoded_text como texto no confiable: no lo renderice como HTML ni abra automáticamente una URL decodificada. Los fotogramas de evidencia se referencian mediante rutas del paquete.| campo | Tipo | Notas |
|---|---|---|
| estado | cuerda | QUEUED, PROCESSING, COMPLETED, FAILED, REJECTED o PARTIAL solo para lotes. |
| nivel | objeto | solicitada/requerida/efectiva/facturada, más los motivos por los que se requirió la prima. |
| uso.units_total | entero | Unidades facturables para el trabajo. |
| facturación | objeto | Moneda, precio unitario y unidades e importe estimado frente a final. |
| paquete.download_url | cuerda | Paquete que vence y tiene alcance de trabajo URL. Solo punto final de un solo trabajo. |
| medios de comunicación | objeto | Cuál fue realmente la entrada, como se probó en el envío. Nulo en trabajos más antiguos. |
| medios.video.ancho/alto | entero | Mostrar dimensiones, rotación ya aplicada. |
| medios.duration_sec | numero | Ausente para imágenes fijas, que no tienen línea de tiempo. |
| metadata | objeto | El objeto metadatos que envió se repitió. |
| error | cuerda | Presente en FAILED, REJECTED o PARTIAL solo para lotes; null en caso contrario. |
Reglas de votación
- Prefiere webhooks; Encuesta sólo cuando no puedas recibir una.
- Página con next_cursor, nunca un desplazamiento: las filas cambian a medida que se actualizan los trabajos.
- Una identificación de trabajo que no es de su propiedad devuelve 404, lo mismo que una que no existe.
- Las filas de la lista omiten el paquete URL; busque el trabajo único para descargar.
- Retroceda entre encuestas. El estado de una terminal no cambiará.
Prepago, pago sobre la marcha y liquidación según el uso real.
Agregue una tarjeta, deposite fondos en la billetera y envíe trabajos sin una suscripción recurrente. MediaRuntime reserva un presupuesto antes de la ejecución y liquida el cargo final cuando el trabajo llega a un estado terminal.
| Planificar | Precio de uso inicial | Recarga mínima | Recarga automática predeterminada |
|---|---|---|---|
| Standard Pay-As-You-Go | Desde $0.02 | $5.00 | $5.00 en $2.00 disponible |
| Premium Pay-As-You-Go | Desde $0.05 | $20.00 | $20.00 en $5.00 disponible |
billing y usage para conciliar.Reglas de billetera
- El crédito disponible equivale al crédito de billetera menos los fondos reservados para ejecutar trabajos.
- El crédito disponible insuficiente devuelve HTTP 402 antes de la ejecución.
- La recarga automática es opcional y requiere una tarjeta registrada.
- Una solicitud exclusiva de Premium devuelve 403 cuando no se permite la actualización.
Reintentar fallas de transporte, no trabajo no válido.
Cada respuesta incluye X-Request-Id. Los errores añaden un objeto error normalizado y conservan detail/message por compatibilidad. Registre el ID de solicitud, el código y el estado, pero nunca la clave API, las URL firmadas ni el cuerpo de la solicitud.
| Estado | Código | Significado | Qué debe hacer tu integración |
|---|---|---|---|
| 400 | invalid_request | La solicitud es lógicamente inválida o el estimador la rechazó. | Arreglar la solicitud; no lo vuelva a intentar sin cambios. |
| 401 | authentication_error | La clave API no es válida, ha caducado o está revocada. | Corrija o gire la clave; no lo vuelvas a intentar ciegamente. |
| 402 | billing_required | La cuenta, la billetera o la verificación previa de facturación no pueden cubrir el trabajo. | Deposite fondos en la billetera o resuelva la facturación primero. |
| 403 | permission_denied | El plan, rol o característica no permite la solicitud. | Cambiar el plan/solicitud; no lo vuelva a intentar sin cambios. |
| 404 | not_found | El recurso propio no existe o está oculto por el ámbito del propietario. | Corrija el identificador; no lo vuelva a intentar sin cambios. |
| 409 | idempotency_in_progress / conflict | Una operación con esta clave sigue en curso o entra en conflicto con otra operación activa. | Reintente solo cuando error.retryable sea true. |
| 410 | gone | Un token de corta duración ha caducado. | Obtenga un resultado o token nuevo. |
| 413 | request_too_large | El cuerpo de la solicitud HTTP supera los 2 MiB. | Cargue medios por separado y envíe URL únicamente. |
| 422 | validation_error / idempotency_conflict / unprocessable_entity | La validación falló o una clave de idempotencia se reutilizó con otro cuerpo. | Corrija el campo o la clave indicados. |
| 429 | rate_limited | La cuenta o clave tiene una tarifa limitada. | Vuelva a intentarlo con retroceso exponencial y fluctuación. |
| 500 | internal_error | La pasarela falló de forma inesperada. | Vuelva a intentarlo de forma segura con retroceso. |
| 502 | upstream_error | Falló una dependencia transitoria de la plataforma. | Vuelva a intentarlo de forma segura con retroceso. |
| 503 | service_unavailable | Una dependencia o vía de ejecución no está disponible. | Vuelva a intentarlo de forma segura con retroceso. |
{
"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 pequeña superficie que necesitan la mayoría de integraciones.
Todos los puntos finales de servidor a servidor a continuación utilizan X-API-Key. El paquete tokenizado URL es la única excepción porque lleva su propia credencial de corta duración y con ámbito de trabajo.
| Método | Camino | Propósito |
|---|---|---|
| PUBLICAR | /v1/upload-url | Opcionalmente, cree un objetivo de carga de 15 minutos cuando aún no tenga un medio recuperable URL. |
| PUBLICAR | /v1/jobs | Ponga en cola un trabajo de medios de entrada única o por lotes. |
| OBTENER | /v1/jobs/{job_id} | Estado, decisión de nivel, uso, facturación y enlace de paquete para un trabajo. |
| OBTENER | /v1/jobs | Enumere sus trabajos, los más nuevos primero. Admite ?status= y paginación del cursor. |
| OBTENER | /v1/jobs/{job_id}/moderation | Veredicto de moderación de un trabajo. Devuelve 404 cuando no se solicitó moderación. |
| GET | /v1/jobs/{job_id}/clip-candidates | Revisa antes de renderizar |
| OBTENER | /v1/jobs/{job_id}/media-report | Informe de medios forenses para un trabajo. 404 cuando no se solicitó media_report_v1. |
| OBTENER | /v1/jobs/{job_id}/compatibility-report | Veredicto de compatibilidad versionado. 404 cuando no se solicitó compatibility_report_v1. |
| OBTENER | /v1/jobs/{job_id}/codes | Detecciones QR y de códigos de barras limitadas con referencias de evidencia. 404 cuando no se solicitó code_detect_v1. |
| OBTENER | /v1/jobs/{job_id}/bundle?token=... | Canjee el token de ámbito de trabajo por un paquete; no se requiere ninguna clave API. |
| PUBLICAR | /v1/jobs/{job_id}/retry-webhook | Vuelva a intentar el webhook de terminal para un trabajo de su propiedad. |
| PUBLICAR | /v1/account/watermark-logo/upload-url | Cree un destino de carga para el logotipo de la cuenta PNG. |
| PUBLICAR | /v1/account/watermark-logo/confirm | Confirme el logotipo y su configuración de ubicación. |
Usa el documento OpenAPI 3.1 versionado para generar clientes, validar solicitudes y revisar el contrato. Solo contiene la API pública admitida y no requiere una clave de API.