Glowb Dev Docs
SaaS API제출 링크 (매직 링크)

POST /ai/submit-link/{token}/complete/review

1·2차 검수 제출 완료 콜백 (무인증)

1·2차 검수 제출 완료 콜백

GCS 직접 업로드가 끝난 뒤 호출하여 1차·2차 검수 제출을 처리합니다. 내부적으로 기존 일괄 제출 로직을 그대로 호출하므로, 상태변경·피드백 해결·알림이 인앱 제출과 동일하게 발생합니다.

처리 순서

  1. 토큰 검증 + reviewId가 토큰의 신청에 속하는지 확인 (다른 신청 제출 방지)
  2. 비디오 항목은 트랜스코딩 트리거 (인앱 업로드와 동일한 호출)
  3. 기존 일괄 제출(batchSubmit) 호출 → 저장 · 제출 · 피드백 해결 · 알림
  4. 제출 성공 → 토큰 1회용 소진 (재제출/2차는 새 링크 필요)

HTTP 요청

POST /ai/submit-link/{token}/complete/review
Content-Type: application/json

Path Parameters

파라미터타입필수설명
tokenstring제출 링크 토큰

Request Body

{
  "reviewId": 50,
  "items": [
    {
      "itemId": 1,
      "itemType": "VIDEO",
      "filePath": "https://storage.googleapis.com/glowb-input/campaign/content/link/100/...mp4",
      "comment": null
    },
    {
      "itemId": 3,
      "itemType": "CAPTION",
      "editorState": "{\"root\":{\"children\":[]}}"
    }
  ]
}
필드명타입필수설명
reviewIdlong제출할 검수 라운드 ID (컨텍스트에서 조회)
itemsarray제출물 목록 (기존 일괄 제출과 동일 구조)
items[].itemIdlong조건부제출물 ID (기존 항목 수정 시 필수)
items[].itemTypestring조건부제출물 타입 (신규 시 필수)
items[].scriptIndexinteger아니오장면 번호(0부터). SCRIPT_VIDEO/SCRIPT_BLOG 다중 장면용. 생략 시 서버가 자동 부여(첫 항목=0). 그 외 타입은 무시
items[].filePathstring조건부GCS URL (publicUrl) — VIDEO/PHOTO 필수
items[].editorStatestring아니오에디터 상태 JSON을 문자열로 직렬화(stringify) 한 값 (SCRIPT_VIDEO/SCRIPT_BLOG/CAPTION/HASHTAG). ⚠️ 객체 {}로 보내면 JSON parse error로 실패 — 반드시 문자열
items[].commentstring아니오코멘트

다중 장면 스크립트 (Multi-Scene)

SCRIPT_VIDEO장면별로 여러 항목을 보낼 수 있습니다. 각 장면을 scriptIndex로 구분하면 서버가 장면별 레코드로 저장합니다(같은 reviewId·같은 scriptIndex로 재제출하면 해당 장면을 덮어쓰기=upsert). 단일 장면이면 scriptIndex를 생략해도 됩니다(자동 0).

SCRIPT_VIDEO 항목의 editorState는 장면 구성을 위해 videoScene/subtitle/narration 3개 필드를 담은 JSON을 문자열로 직렬화해 보냅니다(각 필드 선택, 기존 단순 Lexical {"root":...} 형식도 그대로 호환).

{
  "reviewId": 50,
  "items": [
    {
      "itemType": "SCRIPT_VIDEO",
      "scriptIndex": 0,
      "editorState": "{\"videoScene\":{\"root\":{...}},\"subtitle\":{\"root\":{...}},\"narration\":{\"root\":{...}}}"
    },
    {
      "itemType": "SCRIPT_VIDEO",
      "scriptIndex": 1,
      "editorState": "{\"videoScene\":{\"root\":{...}},\"subtitle\":{\"root\":{...}},\"narration\":{\"root\":{...}}}"
    }
  ]
}

editorState는 항상 stringify된 문자열입니다. 위 예시의 videoScene/subtitle/narration 객체도 통째로 JSON.stringify(...) 한 문자열로 보내야 합니다(객체째 전송 시 파싱 실패). 백엔드는 editorState를 그대로 저장하고 v4 AI 스크립트 검수에 장면별로 전달합니다.

응답

성공 응답 (200 OK) — 기존 일괄 제출과 동일한 BatchResponse

{
  "status": 200,
  "code": null,
  "message": "제출 완료",
  "data": {
    "reviewId": 50,
    "items": [ { "id": 1, "itemType": "VIDEO", "isSubmitted": true } ],
    "resolvedFeedbackCount": 2
  }
}

에러 응답

상황상태 코드메시지
토큰 만료/사용됨400만료되었거나 사용할 수 없는 링크입니다.
검수 라운드 없음400검수 라운드를 찾을 수 없습니다.
다른 신청의 라운드400이 링크로 제출할 수 없는 검수 라운드입니다.
VIDEO/PHOTO 파일 없음400영상/사진 파일을 업로드해주세요.

API 테스트

On this page