API v1生产服务器到服务器

只需几分钟即可交付您的第一份媒体工作。

向 MediaRuntime 提供可访问的媒体 URL,准确请求所需输出,并接收已签名的终态 Webhook。只有在没有现成源 URL 时,才使用可选上传端点。

合同一览
1
来源
使用公共或限时媒体 URL
2
提交
使用 file_url 发布 /v1/jobs
3
确认
存储返回的job_id
4
完成
验证并处理签名的 Webhook
快速入门

提交媒体 URL,然后等待 Webhook。

MediaRuntime 可直接接受公共 HTTP(S) URL 或限时签名读取 URL。该 URL 必须保持可访问,直到 worker 下载输入。提交成功会立即返回 QUEUED;完成的输出随后通过已签名的 Webhook 送达。

cURL
提交现有媒体 URL
# 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 '{
    "file_url": "https://cdn.example.com/media/launch-trailer.mp4",
    "metadata": { "asset_id": "asset_0426", "media_type": "video" },
    "outputs": [{
      "type": "mp4",
      "preset": "mp4_720p_h264_aac",
      "poster_time_sec": 2
    }]
  }'
带上您现有的媒体 URL
将 `file_url` 设置为公共 HTTP(S) URL 或来自您已使用的存储的短期签名读取 URL。它必须通过排队和工作人员的源下载保持可访问。 MediaRuntime 不需要成为源文件的记录系统。
将 job_id 作为您的耐用钥匙
将其与您自己的实体 ID 一起保留。您的 元数据 在 Webhook 中回显,使协调变得简单。
Bash
本地字节的可选上传
# 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 file_url in POST /v1/jobs.
JSON
立即响应
{
  "job_id": "job_1320c28b72104811b075a26a99496cf6",
  "status": "QUEUED",
  "tier": "standard",
  "msg": "accepted"
}
认证

将 API 密钥保留在您的服务器上。

从帐户 → API 密钥创建密钥。原始密钥仅显示一次并属于您的秘密管理器,而不是浏览器代码、移动二进制文件、日志或源代码控制。

标头

在每个 /v1 请求上发送 X-API-Key。

存储

将 MEDIARUNTIME_API_KEY 存储在服务器端秘密管理器中。

旋转

创建替换密钥,部署它,验证流量,然后撤销旧密钥。

X-API-Key: sk_live_…
创造就业机会

让元数据完成集成关联。

wMedia 使用的生产模式有意保持简单:提交输入、输出配方以及足够的不透明元数据,以便将终态事件关联回您自己的数据库记录。

JSON
生产式要求
{
  "file_url": "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 }
      ]
    }
  ]
}
领域
file_url
类型
字符串
注释
一个公共 HTTP(S)、限时签名 HTTP(S) 或可访问的 gs:// 输入。使用此或 输入,切勿同时使用。
领域
inputs
类型
数组
注释
1–25 输入 的批量扇出。每个都可以携带 input_id 和 元数据。
领域
outputs
类型
数组
注释
1–10 个输出配方。每个都需要类型;强烈推荐预设。
领域
metadata
类型
对象
注释
JSON 高达 32 KiB。在meta.request_metadata 上坚持并回应。
领域
moderation
类型
对象
注释
Premium 视觉媒体 检查:性、暴力、危险。
领域
watermark
类型
对象
注释
Premium 视觉媒体叠加。该帐户必须已有 PNG 徽标。

批量扇出

当每个输入需要相同的 输出 时,请使用批处理。每个输入 元数据 合并到每个子作业中;父作业将成为您的批次参考。

JSON
2个输入,1个输出配方
{
  "inputs": [
    {
      "file_url": "https://cdn.example.com/a.mp4",
      "input_id": "asset-a",
      "metadata": { "position": 0 }
    },
    {
      "file_url": "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" }]
}

使用 Idempotency-Key 安全重试

超时请求是不明确的:作业可能已排队,但仅丢失了响应。发送 Idempotency-Key 标头并重试是安全的 - 相同的密钥返回原始作业,而不是排队并为第二个作业收费。如果没有标头,行为不会改变,并且每个 POST 都会创建一个新作业。

Bash
安全地重试相同的提交
# 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 '{
    "file_url": "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.
您生成密钥,而不是我们
MediaRuntime 无法自行区分两个请求 - 只有您的客户端知道第二次调用是重试而不是新工作。每个逻辑作业生成一个密钥,并在该作业的每次重试中重复使用它。在重试循环内生成密钥将为每次尝试提供一个新密钥并完全消除保护。

关键规则

  • UUID 有效;像 asset_0426:mp4_720p:v1 这样的确定性 ID 更好,因为您可以在崩溃后重新生成它。
  • 密钥的范围仅限于您的帐户,并且 24 小时内有效。
  • 重复使用具有不同主体的密钥会返回 422 — 通常在循环中重复使用一个密钥。
  • 当第一个仍在运行时发送的重试返回 409;短暂退避后重试。
  • 故意提交同一个文件两次?使用两个不同的键。
输出预设

选择您希望引擎生成的工件。

`type` 和 `preset` 共同构成可执行配方。请使用下方列出的准确 `type`:只有 `preset` 名称不会改变输出类型,不匹配的组合可能被拒绝或错误路由。

JSON
垂直社交视频
{
  "file_url": "https://cdn.example.com/landscape-interview.mp4",
  "outputs": [{
    "type": "social",
    "preset": "social_vertical_blur"
  }]
}
社交执行什么
social_vertical_blur 创建 1080×1920 H.264/AAC MP4。源被缩放以适应而不裁剪;其后面的 9:16 画布上充满了模糊的副本。将其用于 Reels、TikTok 和 Shorts。它是 Premium 配方,因为垂直输出高为 1920 像素。

视频文件和海报

预设
mp4_720p_h264_aac (type: mp4)
发送
视频
作业执行
720p H.264/AAC MP4 具有快速启动功能,可进行网络播放。
基础层
Standard
预设
mp4_ladder_v1 (type: mp4)
发送
视频
作业执行
三个 MP4 版本(1080p、720p 和 480p),以及每个版本的海报。
基础层
Standard
预设
transmux_mp4_fast (type: mp4)
发送
兼容的音频/视频
作业执行
将现有流复制到快速启动 MP4 中,无需重新编码。如果复制失败并且启用了回退,引擎将使用 720p H.264 预设 重新编码。
基础层
Standard
预设
poster_frame_v1 (type: mp4)
发送
视频
作业执行
在 poster_time_sec 处捕获的一张 720p JPG。请求类型仍然是mp4。
基础层
Standard
预设
mp4_hevc_1080p (type: mp4)
发送
视频
作业执行
1080p HEVC/H.265 + AAC MP4 带有适用于 Apple 播放的 hvc1 标签。
基础层
Premium
预设
mp4_av1_smart (type: mp4)
发送
视频
作业执行
1080p AV1 + Opus MP4 针对压缩效率进行了优化;编码是 CPU 密集型的。
基础层
Premium
预设
mov_prores_422 (type: mp4)
发送
视频
作业执行
ProRes 422 HQ + PCM MOV 编辑大师。保留源尺寸并生成大的夹层文件。
基础层
Premium

社交视频

预设
social_vertical_blur (type: social)
发送
视频
作业执行
1080×1920 H.264/AAC MP4。适合 Reels、TikTok 和 Shorts 的模糊 9:16 背景。
基础层
Premium

动画 GIF

预设
gif_hq (type: gif)
发送
视频
作业执行
使用调色板生成以 480 像素宽度和 15 fps 制作动画 GIF,以获得更好的颜色质量。
基础层
Standard

帧提取

预设
extract_frames_1 (type: frames)
发送
视频
作业执行
编号为 JPG 的帧序列以每秒 1 帧的速度采样。
基础层
Standard
预设
extract_frames_5 (type: frames)
发送
视频
作业执行
编号为 JPG 的帧序列以每秒 5 帧的速度采样。
基础层
Standard
预设
scene_detect_v1 (type: frames)
发送
查看输入规则
作业执行
Detects shot boundaries and exports one keyframe per shot (scene_00001.jpg…), plus scenes.txt with each boundary's timestamp and score. Frame count equals shot count — a single continuous take yields one.
基础层
各不相同
预设
perceptual_hash_v1 (type: frames)
发送
查看输入规则
作业执行
Fingerprints the video by sampling one frame per second and reducing each to a 64-bit dHash, written to phash.json. Compare two videos with Hamming distance to answer “is this the same content?” — it survives re-encoding and rescaling, where a checksum does not. Useful for deduplication and reupload detection. Not crop-invariant.
基础层
各不相同

流媒体

预设
hls_ladder_v1 (type: hls)
发送
视频
作业执行
HLS VOD 包,包含 1080p 和 720p H.264/AAC 变体、主播放列表和 6 秒片段。
基础层
Standard

音频

预设
audio_copy_fast (type: audio)
发送
音频或带音频的视频
作业执行
复制源音频流而不重新编码。如果复制失败并且启用了回退,引擎将改为写入 128 kbps AAC。
基础层
Standard
预设
audio_aac_128k (type: audio)
发送
音频或带音频的视频
作业执行
快速启动 M4A 文件中的 128 kbps AAC。
基础层
Standard
预设
audio_mp3_128k (type: audio)
发送
音频或带音频的视频
作业执行
128 kbps MP3 文件。
基础层
Standard
预设
audio_opus_96k (type: audio)
发送
音频或带音频的视频
作业执行
96 kbps Opus 文件,非常适合语音传送。
基础层
Standard
预设
audio_loudnorm_aac_128k (type: audio)
发送
音频或带音频的视频
作业执行
标准化为 -16 LUFS,然后写入 128 kbps AAC。
基础层
Standard
预设
audio_trim_silence_aac_128k (type: audio)
发送
音频或带音频的视频
作业执行
删除前导和尾随静音,然后写入 128 kbps AAC。
基础层
Premium
预设
audio_loudnorm_trim_aac_128k (type: audio)
发送
音频或带音频的视频
作业执行
修剪边界静默,标准化为 -16 LUFS,然后写入 128 kbps AAC。
基础层
Premium
预设
audio_whisper_prep (type: audio)
发送
音频或带音频的视频
作业执行
16 kHz 单声道 PCM WAV 为 Whisper、ASR 或其他语音管道准备。
基础层
Premium

图像衍生品

预设
image_multi_v1 (type: image)
发送
图片
作业执行
使用 fit、fill、cover 或 contains 创建您请求的图像数组。层级取决于格式、大小、数量、智能裁剪和背景去除。
基础层
Standard 或 Premium
预设
media_report_v1 (type: image)
发送
查看输入规则
作业执行
Inspects the file without transcoding it and writes media_report.json: container and stream detail, encoder strings, GOP/keyframe structure, and EXIF including GPS coordinates converted to decimal degrees. This READS metadata rather than stripping it — image renditions still strip metadata as before. Accepts video or images; audio-only inputs are not supported.
基础层
各不相同
流复制兼容性
当源与 MP4 兼容时,transmux_mp4_fast 避免了质量改变编码。如果复制失败并且启用了回退,引擎将使用 mp4_720p_h264_aac 重新编码;当您需要可预测的输出特性时,请直接使用 预设。
等级可以随着覆盖而上升
该表显示 Workspace 的基础层级。额外的图像输出、WebP/AVIF、大型图像集、智能裁剪、背景移除、水印、内容审核、高级字幕或 GIF 预览可能需要 Premium。
格式转换

使用一个来源。生成您的产品所需的格式和边车工件。

源扩展不选择输出。 类型 和 预设 选择可执行配方,因此上传的视频可以在同一异步作业中成为播放视频、纯音频媒体、脚本、GIF 预览、海报或帧序列。

来源
JPG、PNG 或 WebP
可交付成果
JPG、PNG、WebP 或 AVIF 衍生物
食谱
图像+image_multi_v1;选择图像[].格式、尺寸、mode 和质量。
来源
视频
可交付成果
Web MP4、HLS、社交视频或编辑大师
食谱
选择匹配的 mp4、hls 或社交 预设。
来源
视频
可交付成果
动画 GIF、海报或 JPG 帧序列
食谱
使用 gif_hq、poster_frame_v1、extract_frames_1/5 或将 gif_preview 连接到视频输出。
来源
视频或音频
可交付成果
M4A、MP3、Opus 或语音 WAV
食谱
选择对应的audio_* 预设;视频 输入 已提取其音频流。
来源
视频或音频演讲
可交付成果
SRT、WebVTT 或两者
食谱
将字幕添加到音频或视频输出并选择 srt、vtt 或两者。
JSON
PNG → JPG + WebP
{
  "file_url": "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 }
    ]
  }]
}
JSON
一个视频 → MP4 + MP3
{
  "file_url": "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" }
  ]
}
JSON
视频 → M4A + SRT + WebVTT
{
  "file_url": "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
    }
  }]
}
JSON
视频 → MP4 + 海报 + GIF 预览
{
  "file_url": "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
    }
  }]
}
JSON
视频 → HLS 自适应流媒体包
{
  "file_url": "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"
  }]
}
JSON
视频 → 独立 GIF + JPG 帧序列
{
  "file_url": "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 是一个包,而不是一个视频文件
hls_ladder_v1 创建主播放列表、1080p 和 720p H.264/AAC 变体播放列表以及 6 秒媒体片段。使用报告的主播放列表 URL,或将整个捆绑包一起移动。
专用 GIF 与附加预览
gif_hq 创建完整的 480px、15 fps 主 GIF。 gif_preview 将更短、明确定时的 GIF 添加到另一个视频输出。帧预设以每秒一帧或五帧的速度返回编号为 JPG 的序列。
每个工件都与工作相关
阅读已完成作业的输出清单或使用其品牌捆绑包 URL。音频、文字记录、海报、预览和播放文件均包含在内,无需再次上传源。不要构造文件名或存储路径。
估计完整的输出集
MediaRuntime 在执行之前估计每个请求的输出和功能。 GIF 预览、WebP/AVIF 衍生品、高级字幕和多输出作业可能需要 Premium; API 并没有默默地忽略它们。

有用的开关

audio_aac_128k 返回 M4A,audio_mp3_128k 返回 MP3,audio_opus_96k 返回 Opus,audio_whisper_prep 返回 16 kHz 单声道 WAV。将 subtitles.format 设置为 srtvttboth。仅针对一张海报图像,发送 type: mp4 以及 preset: poster_frame_v1 和所需的 poster_time_sec

食谱

从预设开始;仅覆盖重要的内容。

预设使请求保持可读性并为引擎提供稳定的基线。仅当产品需要时才添加显式再现、字幕、预览、编解码器或比特率选项。

JSON
响应式图像衍生品
{
  "file_url": "https://cdn.example.com/source.jpg",
  "outputs": [{
    "type": "image",
    "preset": "image_multi_v1",
    "images": [
      { "width": 1200, "height": 630, "mode": "cover", "format": "webp", "quality": 84 },
      { "width": 320, "height": 320, "mode": "cover", "format": "webp", "quality": 78 }
    ]
  }]
}
JSON
音频和文字记录文件
{
  "file_url": "https://cdn.example.com/interview.wav",
  "outputs": [{
    "type": "audio",
    "preset": "audio_aac_128k",
    "subtitles": {
      "enabled": true,
      "languages": ["auto"],
      "format": "both",
      "model": "ggml-base.bin"
    }
  }]
}
Premium 功能路由
审核、水印、高级编解码器、多个 输出、GIF 预览以及某些字幕功能可能需要 Premium。 API 拒绝您的帐户无法运行的工作,而不是默默地删除功能。
水印设置
从帐户页面上传并确认一个帐户 PNG。然后只发送{ "watermark": { "enabled": true } }; MediaRuntime 解析服务器拥有的徽标。
适度

在工作中添加分层视觉安全分析。

审核对一幅图像或视频输入使用分层管道:清晰的信号采用快速路径,而不确定或高风险的信号则升级以进行更深入的分析。它通过当前的仅报告合同返回尽力而为的证据和决策,而不会阻止转码。

JSON
请求所有视觉 检查
{
  "file_url": "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"
  }]
}
JSON
已完成作业和 Webhook 的结果
{
  "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 }
  }
}
Contract
Plan
Value
Premium
Notes
The API returns 403 unless the account is Premium or auto-upgrade is allowed.
Contract
Mode
Value
report
Notes
This is the only accepted mode today. Do not send block.
Contract
Checks
Value
sexual, violence, dangerous
Notes
Send one to three checks. Omitting checks selects all three.
Contract
Inputs
Value
One image or video
Notes
Audio-only inputs, batches, and Sandbox moderation are rejected.
Contract
Video sampling
Value
Fixed interval, bounded frames
Notes
The service chooses the interval and cap; read the actual values from result.video and result.evidence.
Contract
Decision
Value
allow, review, or block signal
Notes
Report mode never blocks execution. Use result.verdict, decisions, flagged_checks, and evidence in your own policy.
Contract
Artifact
Value
meta/moderation_result.json
Notes
Included in the output ZIP and exposed through meta.moderation_result.url when available.
Contract
Billing
Value
Separate moderation units
Notes
Estimated and settled with the job at usage.breakdown.moderation_units.
您的应用程序拥有执行权
review 视为人工队列、发布保留或您控制的其他策略的信号。完整的报告并不保证媒体安全、合法或符合政策。
模型可能是错误的
分数是分类器 输出,而不是事实。保留证据,确定下游阈值,在适当的情况下提供上诉路径,并避免完全自动化的高影响力决策。
网络钩子

在信任事件之前验证原始字节。

终端事件至少发送一次,并且不保证订购。验证 HMAC-SHA256、拒绝过时的时间戳、删除重复的 event_id、快速确认并将繁重的工作移至队列。

JSON
COMPLETED事件
{
  "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 下载完整的 ZIP,或获取 meta.engine_result_url 以枚举各个输出和工件路径。
Node
快速原始身体验证
import crypto from "node:crypto";
import express from "express";

const app = express();

// Register this route before any express.json() middleware.
app.post("/webhooks/mediaruntime", express.raw({ type: "application/json" }), (req, res) => {
  const eventId = req.get("X-Transcoder-Id") || "";
  const signatureHeader = req.get("X-Transcoder-Signature") || "";
  const parts = Object.fromEntries(
    signatureHeader.split(",").map((part) => part.trim().split("="))
  );

  const timestamp = parts.t || "";
  const received = parts.v1 || "";
  const ageSeconds = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (!eventId || !timestamp || !received || ageSeconds > 300) {
    return res.sendStatus(401);
  }

  const expected = crypto
    .createHmac("sha256", process.env.MEDIARUNTIME_WEBHOOK_SECRET)
    .update(timestamp + "." + eventId + ".")
    .update(req.body) // raw Buffer; never JSON.stringify(req.body)
    .digest("hex");

  const a = Buffer.from(expected, "utf8");
  const b = Buffer.from(received, "utf8");
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
    return res.sendStatus(401);
  }

  const event = JSON.parse(req.body.toString("utf8"));
  // Enqueue work and deduplicate on event.event_id in your database.
  console.log(event.event_id, event.job_id, event.status);
  return res.sendStatus(200);
});
在账户中配置端点
打开帐户 → Webhooks,输入您的 HTTPS 端点,并在显示签名密钥时存储它。公共 API 集成仅需要您的 API 密钥和 Webhook 签名密钥。

发货规则

  • 仅在签名验证和持久排队/重复数据删除后返回任何 2xx。
  • 将 event_id 视为幂等键。
  • 使用meta.request_metadata 无需第二个查找表即可查找您的实体。
  • 下载保留前的输出.expiresAt。
  • FAILED 或 REJECTED 事件具有 error.code/message 并且没有可用的捆绑包。
跟踪职位

当 webhook 不实用时进行轮询。

提交立即返回,并带有 job_id。 Webhooks 仍然是了解已完成工作的最低延迟方式,但轮询可用于本地开发、没有公共端点的环境、协调和支持问题。

cURL
找一份工作
curl -sS "https://mediaruntime.com/v1/jobs/$JOB_ID" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY"
cURL
列出您的职位
# 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"
JSON
响应字段
{
  "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 是提交作业的 API 密钥的层。 required是工作实际需要的,effective是它运行的车道,billed是你被收费的。运行标准工作的高级钥匙显示 requested: premiumbilled: standard — 您需要支付工作费用,而不是钥匙费用。
读取媒体块
media 报告 MediaRuntime 在提交时探测输入时在您的输入中发现的内容 — 与决定是否接受作业的探测相同。当作业因不兼容的配对而被拒绝时,这解释了原因:发送到图像输出的 MP3 显示 streams.video: 0,而发送到帧输出的静态图像没有 duration_sec。注意 video.width/height 是应用了旋转的显示尺寸,因此纵向手机夹的读数为 1080x1920,即使 encoded_width/encoded_height 为 1920x1080。每个字段都是可选的:缺少一个字段意味着探测器没有报告它,永远不会为零。
获取内容审核判定
GET /v1/jobs/{job_id}/moderation 只返回判定,因此轮询决策的客户端无需每次获取计费和 bundle 详情。响应包含 verdict、每项检查的 decisionconfidence,以及升级的 likelihoods。标记为 review_only 的检查仅供参考:它可以产生 review 判定,但不能单独阻止内容。当作业存在但从未请求内容审核时,端点返回 **404**;空的成功响应会与“已审核但未发现问题”无法区分。每项决策的阈值不公开。
获取媒体报道
GET /v1/jobs/{job_id}/media-report 返回 media_report_v1 文档,而不下载捆绑包。 report 内联携带;异常大的报告不会内联存储,然后响应将 report 设置为 null,而 download_url 仍然可以解析,因此请处理两者。当作业没有报告时返回404。
领域
状态
类型
字符串
注释
QUEUED、正在处理、COMPLETED、FAILED 或已拒绝。
领域
类型
对象
注释
请求/必需/有效/计费,以及需要保费的原因。
领域
用法.units_total
类型
整数
注释
工作的计费单位。
领域
计费
类型
对象
注释
货币、单价以及预计与最终单位和金额。
领域
捆绑包.download_url
类型
字符串
注释
作业范围内、即将到期的捆绑包 URL。仅限单一作业端点。
领域
媒体
类型
对象
注释
输入的实际内容是什么,如提交时所探测的那样。旧作业上为空。
领域
媒体.视频.宽度/高度
类型
整数
注释
显示尺寸,已应用旋转。
领域
媒体.duration_sec
类型
数量
注释
没有静态图像,没有时间线。
领域
metadata
类型
对象
注释
您提交的 元数据 对象已回显。
领域
错误
类型
字符串
注释
填充到 FAILED 或 REJECTED;否则为 null。

投票规则

  • 更喜欢 webhook;仅当您无法收到邮件时才进行轮询。
  • 带有 next_cursor 的页面,从不存在偏移量 — 行随着作业更新而移动。
  • 您不拥有的职位 ID 返回 404,与不存在的职位 ID 相同。
  • 列表行省略捆绑包 URL;获取要下载的单个作业。
  • 在民意调查之间退后一步。终端状态不会改变。
计费和定价

预付费、随用随付、按实际使用情况结算。

添加卡、为钱包充值并提交工作,无需定期订阅。 MediaRuntime 在执行之前保留估计值,并在作业达到最终状态时结算最终费用。

计划
Standard Pay-As-You-Go
起始使用价
来自$0.02
最低充值金额
$20.00
默认自动充值
$20.00 在 $2.00 可用
计划
Premium Pay-As-You-Go
起始使用价
来自$0.05
最低充值金额
$60.00
默认自动充值
$60.00 在 $5.00 可用
预订和结算如何运作
提交保留估计费用加上 15% 安全缓冲。完成对实际计费使用量进行收费并释放未使用的预留。只有在签名的支付 webhook 确认后,待处理的 Stripe 充值才会成为钱包积分。
如何衡量使用情况
视频和音频先按媒体时长计算,再反映所请求的输出和处理。图像使用处理单元,每个作业有最低计费单元;输入字节不按 MB 收费。多个输出以及高级编解码器、字幕、GIF、内容审核和水印等功能可能增加单元或需要 Premium。请使用作业估算进行规划,并使用终态的 billingusage 字段进行对账。

钱包规则

  • 可用信用等于钱包信用减去为运行作业预留的资金。
  • 可用信用不足,执行前返回 HTTP 402。
  • 自动充值是可选的,并且需要存档卡。
  • 当不允许升级时,仅 Premium 请求将返回 403。
使用帐户的账单快照
该表显示了公开的美元起始价格,而不是每个工作的统一价格。协商量帐户可以进行特定于帐户的定价。不要仅根据持续时间得出最终费用;保留为作业返回的估算和终端账单快照。
错误和重试

重试传输失败,而不是无效工作。

大多数 API 错误使用顶级详细信息字段。它可能是字符串或结构化对象,因此请记录整个响应以及相关 ID,但切勿记录 API 密钥。

状态
400
含义
该请求在逻辑上无效或估算器拒绝了它。
您的集成应该做什么
修复请求;不要重试不变。
状态
401
含义
API 密钥无效、过期或已撤销。
您的集成应该做什么
纠正或轮换钥匙;不要盲目重试。
状态
第402章
含义
帐户、钱包或计费预检无法涵盖该作业。
您的集成应该做什么
首先为钱包充值或解决计费问题。
状态
第403章
含义
计划、角色或功能门不允许该请求。
您的集成应该做什么
改变计划/要求;不要重试不变。
状态
第413章
含义
HTTP 请求正文超过 2 MiB。
您的集成应该做什么
单独上传媒体并仅发送 URL。
状态
第422章
含义
JSON 与 API 架构不匹配。
您的集成应该做什么
更正命名字段。
状态
第429章
含义
帐户或密钥受到速率限制。
您的集成应该做什么
使用指数退避和抖动重试。
状态
500/502/503
含义
暂时的平台依赖性失败或通道已暂停。
您的集成应该做什么
通过退避安全重试;保留您的相关性 元数据。
JSON
典型错误体
{
  "detail": "Insufficient wallet balance for this job"
}
安全重试政策
重试 429 和瞬态 5xx 响应,并具有上限指数退避和抖动。丢失 HTTP 响应后不要自动重新提交已接受的作业,除非您的应用程序可以检测到重复项;将您自己的跟踪 ID 保留在 元数据 中以进行协调。
API参考

大多数集成所需的小表面。

以下所有服务器到服务器端点均使用 X-API-Key。标记化捆绑包 URL 是唯一的例外,因为它带有自己的短期、工作范围的凭证。

方法
后处理
路径
/v1/upload-url
目的
当您还没有可获取的媒体 URL 时,可以选择创建 15 分钟的上传目标。
方法
后处理
路径
/v1/jobs
目的
对单输入或批量媒体作业进行排队。
方法
获取
路径
/v1/jobs/{job_id}
目的
一项作业的状态、层决策、使用情况、计费和捆绑链接。
方法
获取
路径
/v1/jobs
目的
列出您的职位,最新的在前。支持 ?status= 和光标分页。
方法
获取
路径
/v1/jobs/{job_id}/moderation
目的
获取单个作业的内容审核判定。未请求内容审核时返回 404。
方法
获取
路径
/v1/jobs/{job_id}/media-report
目的
法医媒体报道了一份工作。 404 当未请求 media_report_v1 时。
方法
获取
路径
/v1/jobs/{job_id}/bundle?token=...
目的
将工作范围的代币兑换为捆绑包;不需要 API 密钥。
方法
后处理
路径
/v1/jobs/{job_id}/retry-webhook
目的
重试您拥有的作业的终端 Webhook。
方法
后处理
路径
/v1/account/watermark-logo/upload-url
目的
为帐户 PNG 徽标创建上传目标。
方法
后处理
路径
/v1/account/watermark-logo/confirm
目的
确认徽标及其位置设置。