영상과 작업
영상은 색인의 단위입니다. 제출할 때마다 video_id를 새로 만들거나 기존 것을 재사용하고, job_id로 식별하는 색인 작업을 시작합니다. 작업은 장면 감지, 캡션 생성, 임베딩, 검수 순서로 비동기 실행됩니다. 작업이 끝나면 영상의 장면, 요약, 레이블을 조회할 수 있고 영상이 검색 대상이 됩니다.
submit ─▶ job: pending ─▶ running ─▶ done ──▶ video indexed (scenes, summary, labels, search)
└▶ failed ─▶ video.status = failed, reason_code set
제출 방법
| 방법 | 엔드포인트 | 반환값 | 참고 |
|---|---|---|---|
| URL 하나 | POST /api/v1/videos | video_id, job_id, created와 함께 202 | 공개적으로 가져올 수 있는 http(s) URL입니다. title은 선택입니다. |
| 파일 하나 | POST /api/v1/videos/upload | video_id, job_id, storage_path와 함께 202 | 멀티파트 업로드입니다. URL 경로와 같은 비동기 흐름을 따릅니다. |
| URL 배치 | kind: "url"로 POST /api/v1/videos/batch | batch_id, 건수, URL마다 items[] 행 하나와 함께 201 | 요청당 최대 500행입니다. 각 행은 요청 순서대로 자체 video_id / job_id / status / error를 담습니다. |
| 파일 배치 | POST /api/v1/videos/batch/upload | batch_id와 accepted / skipped / failed 건수와 함께 202 | 요청당 약 10개 이하 파일을 권장합니다. 500개를 넘으면 413으로 거부합니다. 미리 만든 batch_id를 넘기면 여러 요청에 나눠 업로드할 수 있습니다. |
| URL 시트 | POST /api/v1/videos/batch/upload-sheet | 건수, rejected_rows, items[]와 함께 201 | url 열과 선택 항목인 title 열이 있는 .csv 또는 .xlsx입니다. 시트당 10 MB, 유효 행 500개까지입니다. |
| MRSS 피드 | 대시보드에서 등록하고 GET /api/v1/mrss-feeds 등으로 관리 | 영상이 되는 피드 항목 | 피드는 일정 주기로 폴링됩니다. 수집된 영상은 피드 항목의 guid를 external_content_id로 유지합니다. |
아직 색인 중인 URL을 다시 제출해도 두 번째 파이프라인은 시작되지 않습니다. URL 경로는 기존 video_id / job_id를 created: false와 함께 반환하며(상태 코드는 그대로 202), 배치 행도 submitted 행에 created: false를 담아 같은 방식으로 동작합니다. 파일 업로드는 자연스러운 중복 판별 키가 없으므로, 같은 파일을 다시 보내면 두 번 색인됩니다.
식별자
| 식별자 | 범위 | 안정성 |
|---|---|---|
video_id | 계정 안의 영상 하나입니다. 이후 모든 엔드포인트(/videos/{video_id}, /scenes, 검색 필터, 광고 매칭)에서 사용합니다. | 영상이 존재하는 동안 바뀌지 않습니다. 이 값을 저장하세요. |
job_id | 영상 하나에 대한 색인 시도 하나입니다. | 재색인할 때마다 바뀝니다. 영상의 job_id 필드는 항상 가장 최근에 끝난 시도를 가리킵니다. |
batch_id | 여러 URL이나 파일을 묶은 제출 접수 내역입니다. | 바뀌지 않지만, 제출 결과만 기록하며 색인 진행 상황은 기록하지 않습니다. |
external_content_id | MRSS 피드에서 수집된 영상에 설정되는 고객사 자체 콘텐츠 id입니다. 그 밖에는 null입니다. | content_id=(정확히 일치)로 영상 목록을 필터링합니다. |
작업 상태
status가 done 또는 failed가 될 때까지 GET /api/v1/jobs/{job_id}를 폴링하세요.
status | 의미 |
|---|---|
pending | 대기열에 있으며 파이프라인이 아직 시작되지 않았습니다. |
running | 파이프라인이 실행 중입니다. done_scenes / total_scenes로 장면별 진행률을 추적합니다. |
done | 색인 생성에 성공했습니다. 영상이 색인되어 검색할 수 있습니다. |
failed | 색인 생성에 실패했습니다. 안정적인 원인은 reason_code에서 확인하세요. |
total_scenesinteger이번 시도에서 감지된 장면 수입니다. 장면 감지가 실행되기 전까지는 0입니다.
done_scenesinteger지금까지 분석이 끝난 장면 수입니다.
reason_codestring | null기계가 읽을 수 있는 안정적인 실패 원인입니다. 문서에 나오는 값은 source_forbidden, url_unreachable, media_unreadable, processing_stalled, internal_error입니다. 알 수 없는 값은 불투명한 값으로 취급하세요.
errorstring | null원문 오류 메시지입니다. 끝난 작업에도 이전 시도의 error가 남아 있을 수 있으므로, 이 값을 파싱하지 말고 reason_code로 분기하세요.
started_at / completed_atdate-time | null시도의 실제 시작·종료 시각입니다.
영상 상태와 색인 이력
GET /api/v1/videos/{video_id}와 GET /api/v1/videos는 status 문자열과 함께, 가장 최근에 끝난 색인 시도를 설명하는 이력 필드 4개를 담습니다.
| 필드 | 의미 |
|---|---|
status | 영상의 색인 상태입니다. 스펙에서는 done(색인됨)과 failed를 사용하며, 목록 엔드포인트의 필터로도 쓸 수 있습니다. 이미 done인 영상은 이후 재색인이 실패해도 상태가 그대로이므로, 결과는 job_id로 확인하세요. |
reason_code | 색인 생성이 실패한 이유입니다. status가 failed일 때만 의미가 있고, 그 밖에는 null입니다. |
indexed_at | 가장 최근에 끝난 시도의 종료 시각입니다. 성공 여부와 관계없습니다. 값이 바뀌면 새 시도가 끝났다 는 뜻입니다. 첫 색인 생성이 실행 중이면 null입니다. |
index_trigger | 해당 시도를 시작한 계기로, initial 또는 reindex입니다. 끝난 시도가 없으면 null입니다. |
job_id | indexed_at에 해당하는 작업입니다. 진행 중인 시도는 이 값을 바꾸지 않습니다. |
reindex_run_id | 해당 시도를 만든 재색인 실행의 식별자입니다. 재색인 실행 밖에서는 null입니다. |
놓친 알림을 따라잡으려면 reindexed_since=<timestamp with UTC offset> 또는 reindex_run_id=<uuid>로 영상 목록을 조회하세요. 한 번만 색인된 영상은 두 필터 어느 쪽에도 해당하지 않습니다.
"색인됨"의 의미
작업이 done에 도달하면 영상이 색인 된 것입니다. 이 시점부터 다음이 가능합니다.
GET /api/v1/videos/{video_id}가 AIsummary,genre, IAB 레이블,garm_video평가, 모든 장면의scene_markers,scenes첫 페이지, 영상 전체aggregations를 반환합니다.- 영상의 장면을
POST /api/v1/search로 검색할 수 있고, 광고 매칭에 사용할 수 있습니다. indexed_at,index_trigger,job_id가 채워집니다.
각 필드는 장면과 분석을 참고하세요.
장면을 조회할 수 있는 시점
장면은 작업 전체가 끝나기를 기다리지 않습니다. 장면마다 캡션이 준비되는 즉시 전달됩니다.
| 조회 방식 | 엔드포인트 | 동작 |
|---|---|---|
| 분석이 끝나는 대로 실시간 | GET /api/v1/videos/{video_id}/scenes/stream | NDJSON입니다. scene 이벤트는 scene_index 순서가 아니라 완료 순서로 도착하며, 스트림은 job_status(done, failed, null)를 담은 done 이벤트로 닫힙니다. 이미 색인된 영상에 연결하면 모든 장면을 재전송한 뒤 닫습니다. |
| 작업이 끝난 뒤 | GET /api/v1/videos/{video_id}/scenes | offset / limit(최대 200)으로 페이지를 나눕니다. total은 장면 수입니다. |
| 영상 상세와 함께 | GET /api/v1/videos/{video_id}?scene_limit= | 처음 scene_limit개 장면(기본값 50, 최대 200)과 모든 장면의 가벼운 scene_markers를 반환합니다. |
배치 접수 내역은 진행 상황이 아닙니다
GET /api/v1/videos/batch/{batch_id}는 제출 접수 내역입니다. 각 항목의 status는 제출 시점에 한 번 기록되고 갱신되지 않으므로, 이 값을 폴링하면 끝없이 기다리게 됩니다.
항목 status | 의미 |
|---|---|
submitted | 접수되어 파이프라인에 전달됐습니다. "색인 완료"가 아닙니다. |
skipped | 제출 전에 거부됐습니다(예: 형식이 잘못됐거나 중복된 URL). |
failed | 제출 자체에서 오류가 났습니다. |
pending | 합성 값입니다. counts에만 나타나며, 배치 생성 시 선언했지만 아직 업로드로 채워지지 않은 자리를 뜻합니다. 저절로 줄어들지 않습니다. |
행의 error는 duplicate_url, blocked_target, dispatch_failed, link_failed, submit_failed 같은 안정적인 사유입니다. 파싱 중 제외된 시트 행은 duplicate_url, url_too_long 같은 코드와 함께 rejected_rows에 나열됩니다.
dispatch_failed 행에는 이미 커밋된 영상 행이 있습니다. URL 배치와 시트라면 다시 제출하세요(작업이 실패로 표시되어 아무것도 색인되지 않았습니다). 파일 배치라면 다시 보내지 마세요. 파일이 두 번 색인됩니다.
색인 결과는 항목별 id로 확인하세요. video_id는 GET /api/v1/videos/{video_id}로, job_id는 GET /api/v1/jobs/{job_id}로 조회합니다. 배치 엔드포인트의 job_id는 진행 중인 작업을 포함한 최신 작업이므로, 재색인 중에는 영상 엔드포인트의 값과 다를 수 있습니다.
맞춤 요약
영상에 표준 요약이 생기면, 직접 작성한 지시문에 따라 추가 요약을 요청할 수 있습니다. 표준 결과는 바뀌지 않습니다.
POST /api/v1/videos/{video_id}/custom-summaries에instructions(필수, 최대 2000자), 선택 항목cast(요약에 쓸 수 있는 유일한 인물 이름이며, 없으면 인물 이름을 쓰지 않습니다),language(en,ko같은 언어 태그, 기본값en이며instructions에 적힌 언어보다 우선합니다)를 보냅니다.custom_summary_id,instruction_id,base_version,queued상태의status와 함께202를 반환합니다. 같은 지시문이 이미 범위 밖으로 판단됐다면 즉시rejected를 반환합니다.GET /api/v1/videos/{video_id}/custom-summaries/{custom_summary_id}를 폴링합니다.
status | 의미 |
|---|---|
queued | 준비 중입니다. summary는 null입니다. |
ready | summary에 logline, tone_pacing, setting, themes 섹션이 담깁니다(각각 문자열 또는 null이며, null인 섹션은 notes가 이유를 설명합니다). |
rejected | 지시문이 범위 밖입니다. message에 이유가 담깁니다. |
failed | 생성에 실패했습니다. message에 짧은 사유가 담깁니다. 다시 요청하세요. |
요청 하나는 영상 사용 한도가 아니라 조직의 요약 사용 한도(GET /api/v1/usage의 summaries)에서 1건으로 계산되며, rejected로 끝난 요청도 포함됩니다. failed 요청은 사용 한도에 되돌려집니다. 아직 표준 요약이 없는 영상은 code: custom_summary_no_base_summary와 함께 422를 반환합니다.
MRSS 피드
피드는 대시보드에서 등록합니다. API로는 피드 목록 조회, 피드별 항목 수 조회, enabled·poll_interval_s(3600, 21600, 86400초)·label 변경, 피드 삭제, 피드 항목 페이지 조회를 할 수 있습니다.
GET /api/v1/mrss-feeds/{feed_id}는 두 축의counts를 반환합니다. 제출(pending/submitted/failed)과 색인(indexed_done/indexed_running/indexed_failed)입니다.GET /api/v1/mrss-feeds/{feed_id}/items의 항목에는status(제출),index_status,index_reason_code, 결과video_id가 담깁니다.- 피드를 삭제해도 이미 색인된 영상은
external_content_id와 함께 라이브러리에 남습니다. 나중에 같은 URL을 다시 등록하면 모든 항목을 새 항목으로 처리합니다.