Glowb Dev Docs
SaaS API

Progress Table API

캠페인 진행 상황 관리 API

Progress Table API

캠페인 진행 상황 관리 API입니다.

Base URL: /ai/progress-table

인증 정보

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

엔드포인트 목록

진행 항목 관리

메서드경로설명인증
POST/ai/progress-table/items/admin진행 항목 생성불필요
GET/ai/progress-table/item/{id}캠페인 진행 항목 조회필요
GET/ai/progress-table/items/{id}특정 항목 조회불필요
DELETE/ai/progress-table/items/{id}항목 삭제불필요

매칭 상태

메서드경로설명인증
PUT/ai/progress-table/items/{id}/user/matching-status사용자 매칭 상태 변경불필요
PUT/ai/progress-table/items/{id}/admin/matching-status관리자 매칭 상태 변경불필요
PUT/ai/progress-table/items/bulk/user/matching-status사용자 대량 매칭 상태필요
PUT/ai/progress-table/items/bulk/admin/matching-status관리자 대량 매칭 상태불필요
POST/ai/progress-table/items/bulk/proposal-with-charge예산 자동 충전 + 제안 일괄 처리필요

검수 관리

메서드경로설명인증
PUT/ai/progress-table/items/bulk/admin/ai-checkAI 체크 상태 대량 업데이트불필요
PUT/ai/progress-table/items/bulk/user/ai-check사용자 AI 체크 상태 대량 업데이트필요
PUT/ai/progress-table/items/bulk/user/person-check기업 최종 검수 대량 업데이트필요
PUT/ai/progress-table/items/{id}/ai-check-readyAI 체크 준비 상태 업데이트불필요
PUT/ai/progress-table/reviews/bulk벌크 1차/2차 검수 처리불필요

배송 관리

메서드경로설명인증
PUT/ai/progress-table/items/{id}/delivery-status배송 상태 업데이트불필요
PUT/ai/progress-table/items/{id}/tracking-number추적 번호 업데이트불필요
PUT/ai/progress-table/application/delivery/tracking운송장 번호 저장/수정필요
PUT/ai/progress-table/application/delivery/status/bulk배송 상태 일괄 변경필요
GET/ai/progress-table/application/{applicationId}/delivery배송 정보 조회불필요
GET/ai/progress-table/collab/{collabNo}/delivery-addresses선정된 인플루언서 배송지 목록필요

기타

메서드경로설명인증
PUT/ai/progress-table/items/{id}/admin/upload-url업로드 URL 업데이트불필요
PUT/ai/progress-table/items/{id}/admin/campaign-result캠페인 결과 URL 업데이트불필요
PUT/ai/progress-table/items/{id}/admin/campaign-result-status캠페인 결과 상태 업데이트불필요
PUT/ai/progress-table/items/{id}/bid-price입찰 가격 업데이트불필요
PATCH/ai/progress-table/note/{id}협업 노트 업데이트필요
POST/ai/progress-table/item/please-redo재요청필요
POST/ai/progress-table/final-submissions/bulk벌크 최종 제출물 조회불필요

API 상세

진행 항목 생성

새로운 진행 상황 항목을 생성합니다.

HTTP 요청

POST /ai/progress-table/items/admin
Content-Type: application/json

Request Body

{
  "collabNo": 123,
  "influenceId": "user123",
  "applicationId": 456,
  "matchingStatus": "PENDING"
}

응답

성공 응답 (201 Created)

{
  "status": 201,
  "code": null,
  "message": "새로운 진행 상황 항목이 생성되었습니다.",
  "data": {
    "id": 1,
    "collabNo": 123,
    "matchingStatus": "PENDING"
  }
}

캠페인 진행 항목 조회

기업 대시보드용 캠페인 진행 항목을 조회합니다.

HTTP 요청

GET /ai/progress-table/item/{id}
Authorization: Bearer {access_token}

Path Parameters

파라미터타입필수설명
idlong캠페인 ID

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "캠페인 진행 상황 항목 조회가 완료되었습니다.",
  "data": {
    "step": "MATCHING",
    "items": [
      {
        "id": 1,
        "creator": "인플루언서A",
        "creatorEmail": "influencer_a@example.com",
        "influenceId": 12345,
        "profileImg": "https://s3.../profile.jpg",
        "creatorLink": "https://instagram.com/influencer_a",
        "trackingNumber": "1234567890",
        "uploadUrl": "https://instagram.com/p/xxx",
        "file": null,
        "aiCheckReady": true,
        "matchingStatus": "MATCHED",
        "deliveryStatus": "DELIVERED",
        "aiCheck": "APPROVED",
        "personCheck": "PENDING",
        "campaignResult": null,
        "recommendReason": "높은 참여율",
        "uploadStatus": "UPLOADED",
        "quotePrice": 100000,
        "currentPrice": 80000,
        "collaborationNote": "특별 요청 사항",
        "reviewInfo": {
          "hasNewSubmission": false,
          "reviews": [
            {
              "reviewRound": 1,
              "reviewId": 101,
              "status": "APPROVED",
              "hasNewSubmission": false,
              "submissionItems": []
            }
          ],
          "uploadApproved": true,
          "finalSubmission": null
        },
        "followerCount": 50000,
        "avgViewCount": 10000,
        "rank": "A",
        "rankPrice": 100000,
        "recentPosts": [
          {
            "postId": "abc123",
            "postLink": "https://instagram.com/p/abc123",
            "mediaUrl": "https://video.cdninstagram.com/...",
            "mediaType": "VIDEO",
            "publishedAt": "2025-01-20T14:30:00Z"
          },
          {
            "postId": "def456",
            "postLink": "https://instagram.com/p/def456",
            "mediaUrl": "https://scontent.cdninstagram.com/...",
            "mediaType": "IMAGE",
            "publishedAt": "2025-01-18T10:00:00Z"
          }
        ]
      }
    ],
    "isLegacy": false,
    "totalCount": 10,
    "eliminatedCount": 2,
    "eliminatedPercentage": 20.0,
    "campaignDetails": {
      "no": "123",
      "businessId": "business_001",
      "thumbnailImagePath": "https://s3.../thumbnail.jpg",
      "productImagePath": "https://s3.../product.jpg",
      "productImagePaths": ["https://s3.../product1.jpg"],
      "snsType": "INSTAGRAM",
      "contentFormat": "REEL",
      "category": "BEAUTY",
      "campaignType": "SEEDING",
      "campaignSubStep": "CREATOR_RECRUIT",
      "guidelineStatus": "COMPLETED",
      "productName": "상품명",
      "charge": "100000",
      "currency": "KRW",
      "recruitCount": "10",
      "recruitmentStartDate": "2024-01-01 00:00:00",
      "recruitmentEndDate": "2024-01-31 23:59:59",
      "campaignContractType": "STANDARD"
    },
    "budgetSummary": {
      "totalBudget": 1000000,
      "usedCredit": 300000,
      "refundAmount": 700000,
      "lockedCount": 3,
      "status": "ACTIVE"
    }
  }
}

Response 스키마

ProgressTableWithCampaignResponse

필드명타입설명
stepstring진행 단계 ("MATCHING" | "EXECUTING")
itemsProgressItemExceptBidPriceResponse[]진행 항목 목록
isLegacyboolean레거시 여부
totalCountint전체 항목 수
eliminatedCountint탈락 항목 수
eliminatedPercentagedouble탈락률 (%)
campaignDetailsCampaignFullResponseDto캠페인 상세 정보
budgetSummaryBudgetSummaryDto캠페인 예산 요약 (SaaS 캠페인만)

ProgressItemExceptBidPriceResponse

필드명타입설명
idlong항목 ID
creatorstring크리에이터 이름
creatorEmailstring크리에이터 이메일
influenceIdlong인플루언서 ID
profileImgstring프로필 이미지 URL
creatorLinkstring크리에이터 링크
trackingNumberstring운송장 번호
uploadUrlstring업로드 URL
filestring파일 URL
aiCheckReadybooleanAI 체크 준비 상태
matchingStatusstring매칭 상태
deliveryStatusstring배송 상태
aiCheckstringAI 검수 상태
personCheckstring담당자 검수 상태
campaignResultstring캠페인 결과 URL
recommendReasonstring추천 이유
uploadStatusstring업로드 상태
quotePricelong견적 가격
currentPricelong현재 가격
collaborationNotestring협업 노트
reviewInfoReviewInfo검수 정보
followerCountlong팔로워 수
avgViewCountlong평균 조회수
rankstring랭크 (A/B/C 등)
rankPriceint랭크별 가격
recentPostsPostMediaDto[]최근 게시물 미디어 (최대 3개)

PostMediaDto

필드명타입설명
postIdstring게시물 ID
postLinkstring게시물 링크
mediaUrlstring미디어 URL (video_url 또는 images 중 첫 번째)
mediaTypestring미디어 타입 (VIDEO 또는 IMAGE)
publishedAtdatetime게시일

recentPosts는 PostgreSQL의 post 테이블에서 조회됩니다.

  • video_url이 있으면 mediaType: VIDEO로 반환
  • video_url이 없으면 images의 첫 번째 이미지를 mediaType: IMAGE로 반환

BudgetSummaryDto (SaaS 캠페인만 반환)

필드명타입설명
totalBudgetint캠페인 총 예산 (CAMPAIGN_DEPOSIT 합계)
usedCreditint사용(LOCKED) 금액 합계
refundAmountint환급 가능 금액 (totalBudget - usedCredit)
lockedCountlong잠금된 건수
statusstring상태 ("ACTIVE")

budgetSummary는 SaaS 캠페인(collabNo >= saasNum)에서만 반환됩니다. 레거시 캠페인은 null이 반환됩니다.

예산 관련 에러 응답

매칭 상태를 PROPOSAL로 변경할 때 예산 검증 실패 시 발생하는 에러입니다.

상태 코드에러 코드설명
400NEED_CAMPAIGN_DEPOSIT캠페인 예산이 부족합니다. 추가 입금이 필요합니다.
400INSUFFICIENT_GLOBAL_CREDIT기업 크레딧이 부족합니다. 크레딧을 충전해주세요.
403PROPOSAL_STATUS_CHANGE_NOT_ALLOWED제안 상태의 크리에이터는 기업에서 상태를 변경할 수 없습니다. 관리자에게 문의해주세요.
404BUDGET_NOT_FOUND캠페인 예산 정보를 찾을 수 없습니다.
400BUDGET_ALREADY_LOCKED이미 예산이 예약되어 있습니다.
400BUDGET_ALREADY_UNLOCKED이미 예산이 취소되었습니다.

NEED_CAMPAIGN_DEPOSIT 발생 시: 캠페인 예산 추가 입금 API (POST /ai/payments/collab/confirm)를 호출하세요.

INSUFFICIENT_GLOBAL_CREDIT 발생 시: 크레딧 충전 API (POST /ai/payments/credit/confirm)를 먼저 호출하세요.


사용자 매칭 상태 변경

사용자가 매칭 상태를 변경합니다.

HTTP 요청

PUT /ai/progress-table/items/{id}/user/matching-status?matchingStatus={status}

Path Parameters

파라미터타입필수설명
idlong진행 항목 ID

Query Parameters

파라미터타입필수설명
matchingStatusstring매칭 상태

매칭 상태

상태설명
PENDING대기 중
MATCHED매칭됨
REJECTED거절됨
COMPLETED완료

대량 매칭 상태 업데이트 (사용자)

여러 항목의 매칭 상태를 한번에 업데이트합니다.

HTTP 요청

PUT /ai/progress-table/items/bulk/user/matching-status
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "itemIds": [1, 2, 3, 4, 5],
  "matchingStatus": "MATCHED"
}

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "대량 매칭 상태 업데이트가 완료되었습니다.",
  "data": [1, 2, 3, 4, 5]
}

예산 자동 충전 + 제안 일괄 처리

캠페인 예산이 부족한 경우 글로벌 크레딧에서 자동으로 충전한 후, 선택된 인플루언서들의 상태를 PROPOSAL로 변경하고 예산을 LOCK합니다.

처리 흐름

  1. 선택된 Application들의 총 필요 금액 계산
  2. 캠페인 가용 예산 확인
  3. 예산 부족 시 글로벌 크레딧에서 캠페인 예산으로 자동 충전 (forceCharge=true인 경우)
  4. 각 Application에 대해 예산 LOCK + 상태 PROPOSAL로 변경
  5. 상세 트래킹 정보 반환

HTTP 요청

POST /ai/progress-table/items/bulk/proposal-with-charge
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "collabId": 123,
  "itemIds": [1, 2, 3],
  "forceCharge": true
}

Request Body 스키마

필드명타입필수설명
collabIdlong캠페인 ID (collabNo)
itemIdsarray<long>CampaignApplication ID 목록
forceChargeboolean아니오예산 부족 시 자동 충전 여부 (기본: true)

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "3명의 크리에이터에게 제안을 보냈습니다.",
  "data": {
    "success": true,
    "message": "3명의 크리에이터에게 제안을 보냈습니다.",
    "totalRequested": 3,
    "totalProcessed": 3,
    "totalAmount": 1500000,
    "budgetBefore": 500000,
    "budgetAfter": 0,
    "chargedAmount": 1000000,
    "globalCreditBefore": 5000000,
    "globalCreditAfter": 4000000,
    "processedItems": [
      {
        "applicationId": 1,
        "influenceName": "인플루언서A",
        "amount": 500000,
        "success": true
      },
      {
        "applicationId": 2,
        "influenceName": "인플루언서B",
        "amount": 500000,
        "success": true
      },
      {
        "applicationId": 3,
        "influenceName": "인플루언서C",
        "amount": 500000,
        "success": true
      }
    ],
    "failedItems": null
  }
}

Response Body 스키마

필드명타입설명
successboolean처리 성공 여부
messagestring결과 메시지
errorCodestring실패 시 에러 코드
totalRequestedint요청된 총 인원수
totalProcessedint성공적으로 처리된 인원수
totalAmountint총 차감 금액
budgetBeforeint처리 전 캠페인 가용 예산
budgetAfterint처리 후 캠페인 가용 예산
chargedAmountint글로벌 크레딧에서 충전한 금액 (0이면 충전 없음)
globalCreditBeforeint처리 전 글로벌 크레딧
globalCreditAfterint처리 후 글로벌 크레딧
processedItemsarray성공한 항목별 처리 결과
failedItemsarray실패 항목 (부분 실패 시)

ProposalItemResult 스키마

필드명타입설명
applicationIdlongApplication ID
influenceNamestring인플루언서 이름
amountint차감 금액
successboolean처리 성공 여부
errorMessagestring실패 시 에러 메시지

에러 응답

상태 코드에러 코드설명
400LEGACY_CAMPAIGN레거시 캠페인은 이 기능을 사용할 수 없습니다
400NO_APPLICATIONS처리할 신청 항목이 없습니다
400NO_ELIGIBLE_ITEMS처리 가능한 항목이 없습니다
400BUDGET_001캠페인 예산이 부족합니다 (forceCharge=false일 때)
400BUDGET_002기업 크레딧이 부족합니다

자동 충전이 발생하는 경우

chargedAmount > 0이면 글로벌 크레딧에서 캠페인 예산으로 자동 이체가 발생한 것입니다. 이 경우 CreditTransaction 테이블에 CAMPAIGN_DEPOSIT 타입으로 기록됩니다.

예산 관리 정책

  • 크리에이터 제안 시 예산 LOCK은 CampaignBudget 테이블에서만 관리됩니다
  • CreditTransaction은 글로벌 크레딧 ↔ 캠페인 예산 간 이동 시에만 기록됩니다
  • 제안 취소(UNLOCK) 시에도 CreditTransaction은 기록되지 않습니다

벌크 1차/2차 검수 처리

여러 신청자의 검수 상태를 한번에 승인/반려 처리합니다.

  • 1차 검수 승인 시: 2차 검수 라운드 생성 + Phase를 SECOND_REVIEW로 변경
  • 2차 검수 승인 시: 업로드 허용 + Phase를 UPLOAD_SETTLEMENT로 변경
  • 반려 시: 재제출 상태로 변경 (Phase 유지)

HTTP 요청

PUT /ai/progress-table/reviews/bulk
Content-Type: application/json

Request Body

{
  "applicationIds": [1, 2, 3],
  "action": "APPROVE",
  "reviewRound": 1
}

action 옵션

액션설명
APPROVE승인
REJECT반려

운송장 번호 저장/수정

applicationId로 배송 정보를 저장하거나 수정합니다.

HTTP 요청

PUT /ai/progress-table/application/delivery/tracking
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "applicationId": 123,
  "courier": "CJ대한통운",
  "trackingNumber": "1234567890"
}

배송 상태 일괄 변경

여러 신청의 배송 상태를 일괄 변경합니다.

HTTP 요청

PUT /ai/progress-table/application/delivery/status/bulk
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "applicationIds": [1, 2, 3],
  "deliveryStatus": "SHIPPED"
}

배송 상태

상태설명
beforeDelivery배송 전
shipping배송 중
delivered배송 완료

선정된 인플루언서 배송지 목록 조회

캠페인에서 선정된 인플루언서들의 배송지 정보를 조회합니다. 다운로드용입니다.

HTTP 요청

GET /ai/progress-table/collab/{collabNo}/delivery-addresses
Authorization: Bearer {access_token}

협업 노트 업데이트

진행 항목의 협업 노트를 업데이트합니다.

HTTP 요청

PATCH /ai/progress-table/note/{id}
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "collaborationNote": "특별 요청 사항: 제품 클로즈업 추가 필요"
}

재요청

콘텐츠 재제출을 요청합니다.

HTTP 요청

POST /ai/progress-table/item/please-redo
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "itemIds": [1, 2, 3],
  "rejectReason": "영상 품질 미달"
}

사용 예시

대량 매칭 상태 업데이트

curl -X PUT https://api.glowb.io/ai/progress-table/items/bulk/user/matching-status \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{
    "itemIds": [1, 2, 3],
    "matchingStatus": "MATCHED"
  }'

벌크 검수 처리

curl -X PUT https://api.glowb.io/ai/progress-table/reviews/bulk \
  -H "Content-Type: application/json" \
  -d '{
    "applicationIds": [1, 2, 3],
    "action": "APPROVE",
    "reviewRound": 1
  }'

API 테스트

On this page