Glowb Dev Docs
SaaS API

콘텐츠 검수 API

검수 단계 제출물 및 피드백 관리 API

콘텐츠 검수 API

검수 단계 제출물 및 피드백 관리 API입니다.

Base URL: /ai/influence/contents

인증 정보

항목
인증 필요
인증 방식JWT Bearer Token

엔드포인트 목록

제출물 관리

메서드경로설명인증
GET/ai/influence/contents/{itemId}제출물 조회 (ID)필요
GET/ai/influence/contents/review/{reviewId}/type/{itemType}제출물 조회 (검수라운드+타입)필요
GET/ai/influence/contents/review/{reviewId}검수 라운드별 제출물 목록필요
POST/ai/influence/contents제출물 신규 생성필요
PUT/ai/influence/contents/{itemId}제출물 수정필요
PUT/ai/influence/contents/{itemId}/editor에디터 상태 저장필요
PATCH/ai/influence/contents/{itemId}/submit제출 상태 변경필요

피드백

메서드경로설명인증
PATCH/ai/influence/contents/feedbacks/{feedbackId}/resolve피드백 해결 상태 변경필요
PATCH/ai/influence/contents/feedbacks/{feedbackId}/check피드백 체크 상태 변경 (임시 저장)필요

일괄 제출

메서드경로설명인증
PUT/ai/influence/contents/review/{reviewId}/submit검수 라운드 일괄 제출필요

히스토리

메서드경로설명인증
GET/ai/influence/contents/{itemId}/history제출물 히스토리 조회필요
GET/ai/influence/contents/{itemId}/history/compare버전 비교필요

최종 제작물

메서드경로설명인증
GET/ai/influence/contents/{applicationId}/final-submission최종 제작물 조회필요
POST/ai/influence/contents/{applicationId}/final-submission최종 제작물 저장/제출필요
PATCH/ai/influence/contents/{applicationId}/final-submission최종 제작물 재제출필요

API 상세

제출물 조회 (ID)

제출물 ID로 제출물 상세를 조회합니다. editorState, 피드백 목록을 포함합니다.

HTTP 요청

GET /ai/influence/contents/{itemId}
Authorization: Bearer {access_token}

Path Parameters

파라미터타입필수설명
itemIdlong제출물 ID

제출물 조회 (검수라운드+타입)

검수 라운드 ID와 제출물 타입으로 조회합니다. 이전에 저장한 내용이 있으면 불러옵니다.

HTTP 요청

GET /ai/influence/contents/review/{reviewId}/type/{itemType}
Authorization: Bearer {access_token}

Path Parameters

파라미터타입필수설명
reviewIdlong검수 라운드 ID
itemTypeSubmissionItemType제출물 타입

제출물 타입 (SubmissionItemType)

타입설명
VIDEO영상
SCRIPT스크립트
HASHTAG해시태그
CAPTION캡션

검수 라운드별 제출물 목록 조회

검수 라운드에서 제출해야 할 모든 타입 목록과 각 타입별 저장된 내용을 조회합니다.

HTTP 요청

GET /ai/influence/contents/review/{reviewId}
Authorization: Bearer {access_token}

Path Parameters

파라미터타입필수설명
reviewIdlong검수 라운드 ID

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "조회 성공",
  "data": {
    "reviewId": 88,
    "reviewRound": 1,
    "requiredHashtags": "#브랜드명 #협찬",
    "submissionItems": [
      {
        "itemType": "VIDEO",
        "item": {
          "id": 1,
          "itemType": "VIDEO",
          "filePath": "https://s3.../video.mp4",
          "editorState": {...},
          "status": "REVIEWING",
          "isSubmitted": true
        }
      },
      {
        "itemType": "HASHTAG",
        "item": null
      }
    ],
    "unreflectedFeedbackIds": [1, 2, 3],
    "hasAdditionalReviewRequest": true,
    "needsResubmission": false
  }
}

Response Body 스키마

필드명타입설명
reviewIdlong검수 라운드 ID
reviewRoundint검수 라운드 (1: 1차, 2: 2차)
requiredHashtagsstring캠페인 필수 해시태그
submissionItemsarray제출물 타입별 목록
submissionItems[].itemTypestring제출물 타입
submissionItems[].itemobject저장된 제출물 (없으면 null)
unreflectedFeedbackIdsarray<long>반영되지 않은 피드백 ID 목록 (nullable)
hasAdditionalReviewRequestboolean추가 검수 요청 여부
needsResubmissionboolean크리에이터가 지금 수정/재제출해야 하는지 여부

unreflectedFeedbackIds 필드

기업이 "피드백 미반영" 검수 추가 요청 시 지정한 피드백 ID 목록입니다.

  • 값이 있으면: 해당 피드백들을 하이라이트 표시하여 크리에이터가 재반영해야 함을 안내
  • 값이 null이면: 일반 피드백 목록으로 표시

hasAdditionalReviewRequest 필드

기업이 추가 검수 요청을 했는지 여부를 나타냅니다.

  • true: 기업이 검수 추가 요청을 한 상태 (maxFeedbackCount > 1)
  • false: 일반 검수 진행 중 (maxFeedbackCount = 1)

이 값이 true이면 크리에이터에게 추가 검수 요청이 있음을 안내할 수 있습니다.

needsResubmission 필드

크리에이터가 현재 제출물을 수정하거나 재제출해야 하는지를 나타냅니다.

  • true: 재제출 필요 (제출물이 REJECTED 상태이거나 미제출)
  • false: 제출 완료, 기업 검수 대기 중 또는 승인 완료 (REVIEWING/APPROVED)

프론트엔드 활성화 조건: needsResubmission === true일 때만 편집/제출 버튼 활성화


제출물 신규 생성

새 제출물을 생성합니다.

HTTP 요청

POST /ai/influence/contents
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "reviewId": 1,
  "itemType": "VIDEO",
  "editorState": {...},
  "isSubmit": false
}

Request Body 스키마

필드명타입필수설명
reviewIdlong검수 라운드 ID
itemTypestring제출물 타입
editorStateobject아니오Lexical 에디터 상태 JSON
isSubmitbooleantrue면 제출, false면 임시저장

제출물 수정

기존 제출물을 수정합니다.

HTTP 요청

PUT /ai/influence/contents/{itemId}
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "editorState": {...},
  "isSubmit": true
}

에디터 상태 자동 저장

Lexical 에디터 상태(JSON)만 저장합니다. 자동 저장용입니다.

HTTP 요청

PUT /ai/influence/contents/{itemId}/editor
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "editorState": {...}
}

제출 상태 변경

저장 상태를 제출로 변경하거나 제출을 취소합니다.

HTTP 요청

PATCH /ai/influence/contents/{itemId}/submit
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "isSubmit": true
}

피드백 해결 상태 변경

피드백의 해결 완료 상태를 토글합니다.

HTTP 요청

PATCH /ai/influence/contents/feedbacks/{feedbackId}/resolve
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "isResolved": true
}

피드백 체크 상태 변경 (임시 저장)

크리에이터가 피드백을 확인/반영했음을 임시로 체크합니다. 제출 시 isResolved로 자동 전환됩니다.

checkedByCreator vs isResolved 차이점

  • checkedByCreator: 크리에이터가 피드백을 확인하고 반영 중임을 임시로 표시 (저장 용도)
  • isResolved: 피드백이 최종적으로 해결 완료된 상태 (일괄 제출 시 자동 설정)

HTTP 요청

PATCH /ai/influence/contents/feedbacks/{feedbackId}/check
Authorization: Bearer {access_token}
Content-Type: application/json

Path Parameters

파라미터타입필수설명
feedbackIdlong피드백 ID

Request Body

{
  "isChecked": true
}

Request Body 스키마

필드명타입필수설명
isCheckedbooleantrue: 체크, false: 체크 해제

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "체크 상태 변경 완료",
  "data": {
    "id": 1,
    "feedbackType": "TEXT",
    "content": "해시태그 수정 필요",
    "position": null,
    "isResolved": false,
    "checkedByCreator": true,
    "createdAt": "2025-01-14T10:00:00"
  }
}

검수 라운드 일괄 제출

검수 라운드의 모든 제출물 내용을 저장하고 일괄 제출합니다. 신규 제출과 재제출 모두 이 API를 사용합니다.

주요 동작

  1. 각 제출물의 내용(filePath, editorState, comment)을 저장
  2. 모든 제출물을 제출 상태(isSubmitted=true)로 변경
  3. 해당 검수 라운드의 모든 미해결 피드백을 해결완료(isResolved=true) 처리
  4. 재제출 시 이전 버전은 히스토리로 자동 저장

HTTP 요청

PUT /ai/influence/contents/review/{reviewId}/submit
Authorization: Bearer {access_token}
Content-Type: application/json

Path Parameters

파라미터타입필수설명
reviewIdlong검수 라운드 ID

Request Body

{
  "items": [
    {
      "itemId": 1,
      "itemType": "VIDEO",
      "filePath": "https://s3.../video.mp4",
      "editorState": null,
      "comment": "수정된 영상입니다"
    },
    {
      "itemId": 2,
      "itemType": "CAPTION",
      "filePath": null,
      "editorState": {"root": {...}},
      "comment": null
    },
    {
      "itemId": null,
      "itemType": "HASHTAG",
      "filePath": null,
      "editorState": {"requiredHashtags": ["#브랜드"], "additionalHashtags": ["#추가"]},
      "comment": null
    }
  ]
}

Request Body 스키마

필드명타입필수설명
itemsarray제출할 제출물 목록
items[].itemIdlong조건부제출물 ID (기존 항목 수정 시 필수, 신규 시 null)
items[].itemTypestring조건부제출물 타입 (신규 생성 시 필수)
items[].filePathstring조건부S3 파일 URL (VIDEO, PHOTO 타입은 필수)
items[].editorStateobject아니오Lexical 에디터 상태 JSON (SCRIPT, CAPTION, HASHTAG 타입용)
items[].commentstring아니오코멘트 (선택)

VIDEO/PHOTO 타입 필수 조건

VIDEO 또는 PHOTO 타입으로 제출할 때는 반드시 filePath에 업로드된 파일 URL이 있어야 합니다. 파일 없이 제출하면 에러가 반환됩니다.

  • VIDEO 타입: "영상 파일을 업로드해주세요."
  • PHOTO 타입: "사진 파일을 업로드해주세요."

itemId 사용 규칙

  • 기존 제출물 수정: itemId 필수, itemType 무시됨
  • 신규 제출물 생성: itemId = null, itemType 필수

같은 타입의 제출물이 여러 개 있을 수 있으므로 (히스토리 관리), 반드시 itemId로 식별해야 합니다.

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "일괄 제출 완료",
  "data": {
    "reviewId": 88,
    "items": [
      {
        "id": 1,
        "reviewId": 88,
        "itemType": "VIDEO",
        "filePath": "https://s3.../video.mp4",
        "editorState": null,
        "comment": "수정된 영상입니다",
        "status": "REVIEWING",
        "isSubmitted": true,
        "submittedAt": "2025-01-14T15:30:00",
        "currentVersion": 2,
        "feedbacks": []
      },
      {
        "id": 2,
        "reviewId": 88,
        "itemType": "CAPTION",
        "filePath": null,
        "editorState": {"root": {...}},
        "comment": null,
        "status": "REVIEWING",
        "isSubmitted": true,
        "submittedAt": "2025-01-14T15:30:00",
        "currentVersion": 1,
        "feedbacks": []
      }
    ],
    "resolvedFeedbackCount": 3
  }
}

Response Body 스키마

필드명타입설명
reviewIdlong검수 라운드 ID
itemsarray제출된 제출물 목록
resolvedFeedbackCountint자동으로 해결완료 처리된 피드백 수

에러 응답

상황상태 코드메시지
VIDEO 파일 없음400영상 파일을 업로드해주세요.
PHOTO 파일 없음400사진 파일을 업로드해주세요.
제출물 타입 누락400신규 생성 시 제출물 타입은 필수입니다.
제출물 없음400제출할 제출물이 없습니다.

PUT /items/{itemId} vs PUT /review/{reviewId}/submit 차이점

항목PUT /items/{itemId}PUT /review/{reviewId}/submit
대상단일 제출물검수 라운드 전체
피드백 해결수동 처리 필요자동 일괄 해결
제출 상태isSubmit에 따라 결정무조건 제출 처리
용도개별 저장/제출최종 일괄 제출

제출물 히스토리 조회

제출물의 수정 히스토리를 조회합니다. 현재 버전과 모든 이전 버전 목록을 반환합니다.

HTTP 요청

GET /ai/influence/contents/{itemId}/history
Authorization: Bearer {access_token}

버전 비교

두 버전 간의 변경 내용을 비교합니다. afterVersion이 없으면 현재 버전과 비교합니다.

HTTP 요청

GET /ai/influence/contents/{itemId}/history/compare?beforeVersion={before}&afterVersion={after}
Authorization: Bearer {access_token}

Query Parameters

파라미터타입필수설명
beforeVersionint비교 기준 버전
afterVersionint아니오비교 대상 버전 (없으면 현재 버전)

최종 제작물 조회

업로드/정산 단계에서 최종 제작물을 조회합니다.

HTTP 요청

GET /ai/influence/contents/{applicationId}/final-submission
Authorization: Bearer {access_token}

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "조회 성공",
  "data": {
    "id": 1,
    "applicationId": 123,
    "contentLink": "https://instagram.com/p/...",
    "partnershipCode": "ABC123",
    "cleanFilePath": "https://s3.../clean.mp4",
    "finalFilePath": "https://s3.../final.mp4",
    "isSubmitted": true,
    "submittedAt": "2024-01-15T10:30:00",
    "requiredTypes": ["CONTENT_LINK", "PARTNERSHIP_CODE", "CLEAN_FILE", "FINAL_FILE"],
    "hasReRequest": true,
    "reRequestTypes": ["CONTENT_LINK", "CLEAN_FILE"],
    "reRequestedAt": "2024-01-20T14:00:00"
  }
}

재요청 관련 필드

필드타입설명
hasReRequestboolean재요청 존재 여부
reRequestTypesarray<string>재요청 항목 목록
reRequestedAtdatetime재요청 일시

재요청이 있는 경우

hasReRequesttrue이면 기업에서 해당 항목들에 대해 재제출을 요청한 것입니다. reRequestTypes에 포함된 항목들을 다시 제출해야 합니다.


최종 제작물 저장/제출

업로드/정산 단계에서 최종 제작물을 저장하거나 제출합니다.

HTTP 요청

POST /ai/influence/contents/{applicationId}/final-submission
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "uploadLink": "https://instagram.com/p/...",
  "partnershipCode": "ABC123",
  "files": [
    {
      "fileUrl": "https://s3.../video.mp4",
      "fileName": "final_video.mp4",
      "fileType": "VIDEO"
    }
  ],
  "isSubmit": true
}

파일 업로드는 별도 S3 업로드 API를 사용한 후 URL을 전달합니다.


최종 제작물 재제출

이미 제출한 최종 제작물을 수정하여 재제출합니다. 재요청이 있는 경우 재요청 항목을 클리어하고 재제출 처리합니다.

HTTP 요청

PATCH /ai/influence/contents/{applicationId}/final-submission
Authorization: Bearer {access_token}
Content-Type: application/json

Path Parameters

파라미터타입필수설명
applicationIdlong신청 ID

Request Body

{
  "contentLink": "https://instagram.com/p/...",
  "partnershipCode": "ABC123",
  "cleanFilePath": "https://s3.../clean.mp4",
  "finalFilePath": "https://s3.../final.mp4"
}

Request Body 스키마

필드명타입필수설명
contentLinkstring아니오업로드한 콘텐츠 링크
partnershipCodestring아니오파트너십 코드
cleanFilePathstring아니오클린본 파일 S3 URL
finalFilePathstring아니오최종본 파일 S3 URL

재제출 조건

  • 이미 제출된 상태(isSubmitted=true)에서만 사용 가능
  • 제출된 내용이 없으면 POST API로 최초 제출해야 함
  • null이 아닌 필드만 업데이트됨

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "재제출 완료",
  "data": {
    "id": 1,
    "applicationId": 123,
    "contentLink": "https://instagram.com/p/...",
    "partnershipCode": "ABC123",
    "cleanFilePath": "https://s3.../clean.mp4",
    "finalFilePath": "https://s3.../final.mp4",
    "isSubmitted": true,
    "submittedAt": "2024-01-20T15:00:00",
    "requiredTypes": ["CONTENT_LINK", "PARTNERSHIP_CODE", "CLEAN_FILE", "FINAL_FILE"],
    "hasReRequest": false,
    "reRequestTypes": null,
    "reRequestedAt": null
  }
}

재요청 클리어

재제출 시 기존에 있던 재요청 항목(reRequestTypes)이 자동으로 클리어됩니다.

에러 응답

상황상태 코드메시지
제출물 없음400제출된 최종 제작물이 없습니다. 먼저 제출해주세요.
미제출 상태400아직 제출되지 않은 상태입니다. 최초 제출은 POST API를 사용해주세요.

사용 예시

제출물 생성

curl -X POST https://api.glowb.io/ai/influence/contents \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "reviewId": 1,
    "itemType": "SCRIPT",
    "editorState": {"root": {...}},
    "isSubmit": false
  }'

API 테스트

On this page