API v1프로덕션서버 간 통신

몇 분 만에 첫 미디어 작업을 배포하세요.

한 번 업로드하고 필요한 출력만 정확히 요청한 뒤, 서명된 최종 웹훅을 받으세요. 아래 예제는 실제 프로덕션 연동에서 사용하는 API 계약과 동일합니다.

한눈에 보는 계약
1
업로드
POST /v1/upload-url 호출 후 바이트를 PUT
2
제출
file_uri와 함께 POST /v1/transcode
3
확인
반환된 job_id를 저장
4
완료
서명된 웹훅을 검증하고 처리
퀵스타트

업로드하고 제출한 뒤 웹훅을 기다리세요.

MediaRuntime은 비동기로 동작합니다. 제출에 성공하면 즉시 QUEUED를 반환하고, 완성된 출력은 이후 서명된 웹훅으로 전달됩니다.

cURL
업로드 및 제출
# 1. Ask MediaRuntime for a short-lived upload 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')

# 2. Upload the bytes. Send every returned upload header.
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

# 3. Queue an asynchronous job using the returned file_uri.
curl -sS -X POST "https://mediaruntime.com/v1/transcode" \
  -H "X-API-Key: $MEDIARUNTIME_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --arg file_uri "$FILE_URI" '{
    file_url: $file_uri,
    metadata: { asset_id: "asset_0426", media_type: "video" },
    outputs: [{
      type: "mp4",
      preset: "mp4_720p_h264_aac",
      poster_time_sec: 2
    }]
  }')"
반환된 file_uri를 사용하세요
입력 버킷 경로를 직접 만들지 마세요. 업로드 엔드포인트가 계정 범위에 맞는 올바른 위치를 선택하고 작업에 사용할 정확한 URI를 반환합니다.
job_id를 영구 키로 보관하세요
자체 엔터티 ID와 함께 저장하세요. 보낸 metadata가 웹훅에 그대로 반환되므로 대조 작업이 간단해집니다.
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_…
작업 생성

metadata가 연동 작업을 대신하게 하세요.

wMedia가 사용하는 프로덕션 패턴은 의도적으로 단순합니다. 입력과 출력 레시피, 그리고 최종 이벤트를 자체 데이터베이스 레코드와 다시 연결할 수 있을 만큼의 metadata를 제출하면 됩니다.

JSON
프로덕션 형태의 요청
{
  "file_url": "gs://bucket/path/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
타입
string
설명
gs:// 또는 공개 HTTPS 입력 하나. inputs와 함께 사용할 수 없습니다.
필드
inputs
타입
array
설명
1~25개 입력의 배치 팬아웃. 각 항목은 input_id와 metadata를 가질 수 있습니다.
필드
outputs
타입
array
설명
1~10개의 출력 레시피. 각 항목에 type이 필요하며 preset 지정을 강력히 권장합니다.
필드
metadata
타입
object
설명
최대 32KiB의 JSON. 저장된 뒤 meta.request_metadata로 그대로 반환됩니다.
필드
moderation
타입
object
설명
Premium 시각 미디어 검사: sexual, violence, dangerous.
필드
watermark
타입
object
설명
Premium 시각 미디어 오버레이. 계정에 PNG 로고가 미리 등록되어 있어야 합니다.

배치 팬아웃

모든 입력에 동일한 출력이 필요할 때 배치를 사용하세요. 입력별 metadata는 각 하위 작업에 병합되며, 상위 작업이 배치의 기준이 됩니다.

JSON
입력 두 개, 출력 레시피 하나
{
  "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" }]
}
출력 프리셋

엔진이 생성할 결과물을 선택하세요.

type과 preset이 하나의 실행 가능한 레시피를 이룹니다. 아래에 표시된 type을 정확히 사용하세요. preset 이름만으로는 출력 type이 바뀌지 않으며, 짝이 맞지 않으면 거부되거나 잘못 라우팅될 수 있습니다.

JSON
세로형 소셜 영상
{
  "file_url": "https://cdn.example.com/landscape-interview.mp4",
  "outputs": [{
    "type": "social",
    "preset": "social_vertical_blur"
  }]
}
Social 프리셋의 동작
social_vertical_blur는 1080×1920 H.264/AAC MP4를 만듭니다. 원본을 잘라내지 않고 맞춰 넣고, 흐리게 처리한 복사본이 9:16 캔버스의 배경을 채웁니다. Reels, TikTok, Shorts에 적합합니다. 세로 출력 높이가 1920픽셀이므로 Premium 레시피입니다.

비디오 파일 및 포스터

프리셋
mp4_720p_h264_aac (type: mp4)
전송 대상
비디오
작업 실행 내용
웹 재생을 위해 faststart가 적용된 720p H.264/AAC MP4입니다.
기본 티어
Standard
프리셋
mp4_ladder_v1 (type: mp4)
전송 대상
비디오
작업 실행 내용
1080p, 720p, 480p의 MP4 렌디션 세 개와 각 렌디션의 포스터를 생성합니다.
기본 티어
Standard
프리셋
transmux_mp4_fast (type: mp4)
전송 대상
호환 가능한 오디오/비디오
작업 실행 내용
재인코딩 없이 기존 스트림을 faststart MP4로 복사합니다. 복사가 실패하고 폴백이 활성화되어 있으면 720p H.264 프리셋으로 재인코딩합니다.
기본 티어
Standard
프리셋
poster_frame_v1 (type: mp4)
전송 대상
비디오
작업 실행 내용
poster_time_sec 시점에서 캡처한 720p JPG 한 장입니다. 요청 type은 여전히 mp4입니다.
기본 티어
Standard
프리셋
mp4_hevc_1080p (type: mp4)
전송 대상
비디오
작업 실행 내용
Apple 재생을 위한 hvc1 태그가 적용된 1080p HEVC/H.265 + AAC MP4입니다.
기본 티어
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)
전송 대상
비디오
작업 실행 내용
가로 480px, 15fps 애니메이션 GIF이며 팔레트 생성을 사용해 색상 품질을 높입니다.
기본 티어
Standard

프레임 추출

프리셋
extract_frames_1 (type: frames)
전송 대상
비디오
작업 실행 내용
초당 1프레임으로 샘플링한 번호가 매겨진 JPG 프레임 시퀀스입니다.
기본 티어
Standard
프리셋
extract_frames_5 (type: frames)
전송 대상
비디오
작업 실행 내용
초당 5프레임으로 샘플링한 번호가 매겨진 JPG 프레임 시퀀스입니다.
기본 티어
Standard

스트리밍

프리셋
hls_ladder_v1 (type: hls)
전송 대상
비디오
작업 실행 내용
1080p와 720p H.264/AAC 변형, 마스터 재생목록, 6초 세그먼트로 구성된 HLS VOD 패키지입니다.
기본 티어
Standard

오디오

프리셋
audio_copy_fast (type: audio)
전송 대상
오디오 또는 오디오가 있는 비디오
작업 실행 내용
재인코딩 없이 원본 오디오 스트림을 복사합니다. 복사가 실패하고 폴백이 활성화되어 있으면 128kbps AAC로 기록합니다.
기본 티어
Standard
프리셋
audio_aac_128k (type: audio)
전송 대상
오디오 또는 오디오가 있는 비디오
작업 실행 내용
faststart가 적용된 M4A 파일의 128kbps AAC입니다.
기본 티어
Standard
프리셋
audio_mp3_128k (type: audio)
전송 대상
오디오 또는 오디오가 있는 비디오
작업 실행 내용
128kbps MP3 파일입니다.
기본 티어
Standard
프리셋
audio_opus_96k (type: audio)
전송 대상
오디오 또는 오디오가 있는 비디오
작업 실행 내용
음성 전달에 적합한 96kbps Opus 파일입니다.
기본 티어
Standard
프리셋
audio_loudnorm_aac_128k (type: audio)
전송 대상
오디오 또는 오디오가 있는 비디오
작업 실행 내용
-16 LUFS를 목표로 정규화한 뒤 128kbps AAC로 기록합니다.
기본 티어
Standard
프리셋
audio_trim_silence_aac_128k (type: audio)
전송 대상
오디오 또는 오디오가 있는 비디오
작업 실행 내용
앞뒤 무음을 제거한 뒤 128kbps AAC로 기록합니다.
기본 티어
Premium
프리셋
audio_loudnorm_trim_aac_128k (type: audio)
전송 대상
오디오 또는 오디오가 있는 비디오
작업 실행 내용
경계의 무음을 잘라내고 -16 LUFS로 정규화한 뒤 128kbps AAC로 기록합니다.
기본 티어
Premium
프리셋
audio_whisper_prep (type: audio)
전송 대상
오디오 또는 오디오가 있는 비디오
작업 실행 내용
Whisper, ASR 등 음성 파이프라인을 위해 준비된 16kHz 모노 PCM WAV입니다.
기본 티어
Premium

이미지 파생본

프리셋
image_multi_v1 (type: image)
전송 대상
이미지
작업 실행 내용
fit, fill, cover, contain 중 선택한 방식으로 요청한 images 배열을 생성합니다. 티어는 포맷, 크기, 개수, 스마트 크롭, 배경 제거 여부에 따라 달라집니다.
기본 티어
Standard 또는 Premium
스트림 복사 호환성
원본이 MP4와 호환되면 transmux_mp4_fast는 화질이 바뀌는 인코딩을 피합니다. 복사가 실패하고 폴백이 활성화되어 있으면 mp4_720p_h264_aac로 재인코딩하므로, 출력 특성을 예측 가능하게 유지하려면 해당 프리셋을 직접 사용하세요.
옵션에 따라 티어가 올라갈 수 있습니다
표에 표시된 값은 기본 워크스페이스 티어입니다. 추가 출력, WebP/AVIF 이미지, 대량 이미지 세트, 스마트 크롭, 배경 제거, 워터마크, 콘텐츠 검토, 고급 자막, GIF 미리보기 등은 Premium이 필요할 수 있습니다.
포맷 변환

한 번 업로드하고 제품에 필요한 포맷과 부가 결과물을 만드세요.

원본 확장자가 출력을 결정하지 않습니다. type과 preset이 실행할 레시피를 선택하므로, 업로드한 영상 하나로 재생용 영상, 오디오 전용 미디어, 자막, GIF 미리보기, 포스터, 프레임 시퀀스를 같은 비동기 작업에서 만들 수 있습니다.

원본
JPG, PNG 또는 WebP
결과물
JPG, PNG, WebP 또는 AVIF 파생본
레시피
image + image_multi_v1을 사용하고 images[].format, 크기, mode, quality를 지정합니다.
원본
비디오
결과물
웹 MP4, HLS, 소셜 영상 또는 편집 마스터
레시피
알맞은 mp4, hls 또는 social 프리셋을 선택합니다.
원본
비디오
결과물
애니메이션 GIF, 포스터 또는 JPG 프레임 시퀀스
레시피
gif_hq, poster_frame_v1, extract_frames_1/5를 사용하거나 비디오 출력에 gif_preview를 추가합니다.
원본
비디오 또는 오디오
결과물
M4A, MP3, Opus 또는 음성용 WAV
레시피
해당하는 audio_* 프리셋을 선택합니다. 비디오 입력은 오디오 스트림이 추출됩니다.
원본
비디오 또는 음성 오디오
결과물
SRT, WebVTT 또는 둘 다
레시피
오디오나 비디오 출력에 subtitles를 추가하고 srt, vtt 또는 both를 선택합니다.
JSON
PNG → JPG + WebP
{
  "file_url": "gs://value-returned-by-upload-url",
  "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": "gs://value-returned-by-upload-url",
  "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": "gs://value-returned-by-upload-url",
  "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": "gs://value-returned-by-upload-url",
  "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": "gs://value-returned-by-upload-url",
  "metadata": { "media_type": "video", "asset_id": "stream-0426" },
  "outputs": [{
    "type": "hls",
    "preset": "hls_ladder_v1",
    "path_suffix": "stream"
  }]
}
JSON
영상 → 단독 GIF + JPG 프레임 시퀀스
{
  "file_url": "gs://value-returned-by-upload-url",
  "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, 15fps의 완전한 기본 GIF를 만듭니다. gif_preview는 다른 비디오 출력에 길이가 짧고 시간이 명시된 GIF를 추가합니다. 프레임 프리셋은 초당 1개 또는 5개의 번호가 매겨진 JPG 시퀀스를 반환합니다.
모든 결과물은 작업에 함께 보관됩니다
완료된 작업의 출력 매니페스트를 읽거나 브랜드 번들 URL을 사용하세요. 오디오, 자막, 포스터, 미리보기, 재생 파일이 원본을 다시 업로드하지 않아도 모두 포함됩니다. 파일 이름이나 저장소 경로를 직접 만들지 마세요.
전체 출력 세트를 기준으로 예측됩니다
MediaRuntime은 실행 전에 요청된 모든 출력과 기능을 예측합니다. GIF 미리보기, WebP/AVIF 파생본, 고급 자막, 다중 출력 작업은 Premium이 필요할 수 있으며, API가 이를 임의로 생략하지 않습니다.

알아두면 좋은 옵션

audio_aac_128k는 M4A를, audio_mp3_128k는 MP3를, audio_opus_96k는 Opus를, audio_whisper_prep는 16kHz 모노 WAV를 반환합니다. subtitles.format에는 srt, vtt 또는 both를 지정합니다. 포스터 이미지 한 장만 필요하면 type: mp4preset: 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
완료된 작업과 웹훅의 결과
{
  "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
Express 원본 바디 검증
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);
});
계정에서 엔드포인트 설정
계정 → 웹훅을 열고 HTTPS 엔드포인트를 입력한 뒤, 표시된 서명 비밀값을 보관하세요. 공개 API 연동에는 API 키와 웹훅 서명 비밀값만 있으면 됩니다.

전달 규칙

  • 서명 검증과 영속적인 큐 적재/중복 제거가 끝난 뒤에만 2xx를 반환하세요.
  • event_id를 멱등성 키로 사용하세요.
  • meta.request_metadata를 사용하면 별도의 조회 테이블 없이 엔터티를 찾을 수 있습니다.
  • delivery.expiresAt 이전에 보관된 출력을 내려받으세요.
  • FAILED 또는 REJECTED 이벤트에는 error.code/message가 있으며 사용할 수 있는 번들은 없습니다.
결제 및 요금

선불 충전, 사용한 만큼 결제, 실제 사용량 기준 정산.

카드를 등록하고 지갑을 충전하면 정기 구독 없이 작업을 제출할 수 있습니다. MediaRuntime은 실행 전에 예상 금액을 예약하고, 작업이 최종 상태에 도달하면 최종 금액을 정산합니다.

플랜
Standard Pay-As-You-Go
공개 요금
$0.02/min
최소 충전액
$20.00
기본 자동 충전
잔액 $2.00 시점에 $20.00
플랜
Premium Pay-As-You-Go
공개 요금
$0.05/min
최소 충전액
$60.00
기본 자동 충전
잔액 $5.00 시점에 $60.00
예약과 정산 방식
제출 시 예상 금액에 15%의 안전 버퍼를 더해 예약합니다. 완료 시 실제 청구 대상 사용량을 청구하고 사용하지 않은 예약분은 해제합니다. 대기 중인 Stripe 충전은 서명된 결제 웹훅으로 확인된 뒤에야 지갑 잔액이 됩니다.
비용이 원본 길이와 다를 수 있는 이유
다중 출력과 고급 코덱, 자막, GIF, 콘텐츠 검토, 워터마크 같은 기능은 청구 대상 작업을 늘리거나 Premium을 요구합니다. 계획에는 작업 예상치를, 대조에는 최종 billingusage 필드를 사용하세요.

지갑 규칙

  • 사용 가능 잔액은 지갑 잔액에서 실행 중인 작업에 예약된 금액을 뺀 값입니다.
  • 사용 가능 잔액이 부족하면 실행 전에 HTTP 402를 반환합니다.
  • 자동 충전은 선택 사항이며 등록된 카드가 필요합니다.
  • 업그레이드가 허용되지 않은 상태에서 Premium 전용 요청을 보내면 403을 반환합니다.
계정의 결제 스냅샷을 사용하세요
표는 공개 USD 요금표입니다. 볼륨 계약을 맺은 계정은 계정별 요금이 적용될 수 있습니다. 길이만으로 최종 금액을 계산하지 말고, 작업에 대해 반환된 예상치와 최종 결제 스냅샷을 저장하세요.
오류 및 재시도

전송 실패는 재시도하고, 잘못된 요청은 재시도하지 마세요.

대부분의 API 오류는 최상위 detail 필드를 사용합니다. 문자열일 수도 구조화된 객체일 수도 있으므로 상관관계 ID와 함께 전체 응답을 기록하되, API 키는 절대 기록하지 마세요.

상태 코드
400
의미
요청이 논리적으로 잘못되었거나 추정기가 거부했습니다.
연동에서 해야 할 일
요청을 수정하세요. 그대로 재시도하지 마세요.
상태 코드
401
의미
API 키가 유효하지 않거나 만료 또는 폐기되었습니다.
연동에서 해야 할 일
키를 수정하거나 교체하세요. 무작정 재시도하지 마세요.
상태 코드
402
의미
계정, 지갑 또는 결제 사전 점검이 작업 비용을 감당할 수 없습니다.
연동에서 해야 할 일
먼저 지갑을 충전하거나 결제 문제를 해결하세요.
상태 코드
403
의미
플랜, 역할 또는 기능 제한이 요청을 허용하지 않습니다.
연동에서 해야 할 일
플랜이나 요청을 변경하세요. 그대로 재시도하지 마세요.
상태 코드
413
의미
HTTP 요청 본문이 2MiB를 초과합니다.
연동에서 해야 할 일
미디어는 별도로 업로드하고 URL만 보내세요.
상태 코드
422
의미
JSON이 API 스키마와 일치하지 않습니다.
연동에서 해야 할 일
지정된 필드를 수정하세요.
상태 코드
429
의미
계정 또는 키에 속도 제한이 적용되었습니다.
연동에서 해야 할 일
지수 백오프와 지터를 적용해 재시도하세요.
상태 코드
500/502/503
의미
일시적인 플랫폼 의존성 오류이거나 레인이 중지되었습니다.
연동에서 해야 할 일
백오프를 적용해 안전하게 재시도하고 상관관계 metadata를 유지하세요.
JSON
일반적인 오류 본문
{
  "detail": "Insufficient wallet balance for this job"
}
안전한 재시도 정책
429와 일시적인 5xx 응답은 상한이 있는 지수 백오프와 지터를 적용해 재시도하세요. HTTP 응답을 받지 못했더라도 중복을 감지할 수 없다면 이미 접수된 작업을 자동으로 다시 제출하지 마세요. 대조를 위해 자체 추적 ID를 metadata에 보관하세요.
API 레퍼런스

대부분의 연동에 필요한 최소한의 표면.

아래 서버 간 엔드포인트는 모두 X-API-Key를 사용합니다. 토큰이 포함된 번들 URL만 예외이며, 자체적으로 수명이 짧고 작업 범위로 제한된 자격 증명을 갖습니다.

메서드
POST
경로
/v1/upload-url
용도
입력 버킷에 15분간 유효한 업로드 대상을 생성합니다.
메서드
POST
경로
/v1/transcode
용도
단일 입력 또는 배치 미디어 작업을 큐에 등록합니다.
메서드
GET
경로
/v1/jobs/{job_id}/bundle?token=...
용도
작업 범위 토큰으로 번들을 받습니다. API 키가 필요하지 않습니다.
메서드
POST
경로
/v1/jobs/{job_id}/retry-webhook
용도
본인 소유 작업의 최종 웹훅을 다시 전송합니다.
메서드
POST
경로
/v1/account/watermark-logo/upload-url
용도
계정 PNG 로고용 업로드 대상을 생성합니다.
메서드
POST
경로
/v1/account/watermark-logo/confirm
용도
로고와 배치 설정을 확정합니다.