Glowb Dev Docs
Admin API희망자풀

희망자풀 목록 조회

캠페인 신청 희망자를 크롤 지표와 함께 조회합니다. 같은 사람의 중복 등록은 한 건으로 묶입니다.

희망자풀 목록 조회

캠페인 신청 희망자(collab_applicants)를 PostgreSQL 크롤 지표(팔로워, 평균 조회수·좋아요·댓글, 릴스 지표, 보정 참여율, 랭킹가)와 함께 조회합니다.

이 테이블은 랜딩 폼이 받은 값을 그대로 쌓기 때문에 같은 사람이 여러 번 들어와 있습니다. 이 API는 조회 시점에 중복을 묶어 최신 등록 건만 내려줍니다.

HTTP 요청

GET /ai/admin/collab-applicants
Authorization: Bearer {access_token}

Query Parameters

파라미터타입필수기본값설명
snsTypeString아니오(전체)INSTAGRAM · TIKTOK · YOUTUBE · NAVER · FACEBOOK. 모르는 값은 필터를 걸지 않음. 하위 호환용 — 새 연동은 snsTypes 사용
snsTypesString[]아니오(전체)플랫폼 복수 선택. 하나라도 맞으면 통과. snsTypes=INSTAGRAM,TIKTOK 또는 키 반복
categoryString아니오(전체)협업 카테고리 단일 토큰. CSV 토큰 단위 일치 (BEAUTY가 BEAUTY_TOOL에 걸리지 않음). 하위 호환용 — 새 연동은 categories 사용
categoriesString[]아니오(전체)카테고리 복수 선택. 등록 카테고리와 하나라도 겹치면 통과 (토큰 단위, 대소문자 무시)
countriesString[]아니오(전체)국가 코드 복수 선택 (KR · JP …). 크롤 프로필의 country 기준
createdFrom · createdToLocalDate아니오(없음)등록일 범위 yyyy-MM-dd, 양 끝 포함
keywordString아니오(전체)이름 · 이메일 · 전화번호 · SNS 계정 부분 일치
crawledBoolean아니오(전체)true면 크롤 지표가 있는 사람만, false면 없는 사람만
minFollowers · maxFollowersInteger아니오(없음)팔로워 범위
minAvgViews · maxAvgViewsLong아니오(없음)평균 조회수 범위. 플랫폼에 맞는 컬럼 기준
minRankingPrice · maxRankingPriceInteger아니오(없음)랭킹가 범위. 지정하면 페이지 밖 인원까지 랭킹가를 조회해 거름
sortString아니오CREATED_ATCREATED_AT · FOLLOWERS · AVG_VIEWS · ENGAGEMENT_RATE · RANKING_PRICE
directionString아니오descasc 또는 desc
pageInteger아니오00-based
sizeInteger아니오20최대 200

지표 범위를 지정하면 크롤 데이터가 없는 사람은 제외됩니다. 값이 없는 것을 0으로 쳐서 남기면 "팔로워 1만 이상"에 지표 없는 사람이 섞여 들어오기 때문입니다. 범위를 안 주면 그대로 보입니다.

countries 와 minRankingPrice · maxRankingPrice 도 같습니다. 국가는 크롤 프로필에만 있어 미수집자는 국가 필터에서 빠지고, 랭킹가는 틱톡·네이버가 항상 null 이라 랭킹가 범위를 걸면 그 둘도 빠집니다.

단일 · 복수 파라미터

snsType · category 는 기존 연동을 위해 남겨둔 단일 값입니다. 복수 값(snsTypes · categories)과 함께 오면 합쳐서 봅니다 (snsType=TIKTOK&snsTypes=INSTAGRAM → 틱톡 또는 인스타).

등록일 범위

createdFrom · createdTo 는 snsType 필터처럼 그룹이 아니라 행에 걸립니다. 같은 사람이 3월과 9월에 등록했고 createdTo=2026-03-31 로 조회하면, 범위 안의 3월 등록 건이 대표로 나옵니다.

GET /ai/admin/collab-applicants?snsTypes=INSTAGRAM,TIKTOK&categories=FOOD,TRAVEL&countries=KR&createdFrom=2026-09-01&createdTo=2026-09-30&minRankingPrice=100000

정렬

CREATED_AT 을 뺀 나머지는 크롤 지표라 값이 없는 사람이 섞여 있습니다. 오름차순이든 내림차순이든 값 없는 사람은 항상 뒤로 보냅니다 — 지표순 정렬의 목적이 상위를 추리는 것이라, 빈 값이 앞에 오면 정렬이 무의미해집니다. 동점은 최신 등록순입니다.

AVG_VIEWS 는 플랫폼에 맞는 컬럼을 기준으로 하므로, 인스타는 릴스 평균끼리 · 틱톡은 전체 평균끼리 비교됩니다. RANKING_PRICE 는 틱톡·네이버가 항상 null 이라 그 둘이 전부 뒤로 밀립니다.

모르는 sort 값은 400 대신 CREATED_AT 으로 떨어집니다. avgViews 같은 camelCase 표기도 받습니다.

중복 제거 규칙

정규화된 SNS 핸들 · 이메일 · 전화번호(숫자만) 중 하나라도 겹치면 같은 사람으로 묶습니다. 연결은 전이됩니다 — A와 B가 이메일로 이어지고 B와 C가 전화로 이어지면 A와 C도 한 사람입니다.

  • 대표 행은 가장 최근 등록 건이고, 나머지는 duplicateIds로만 남습니다
  • 전화번호는 숫자 9자리 미만이면 판정에 쓰지 않습니다 (없음 같은 값이 남남을 묶는 것을 막기 위함)
  • snsType 필터는 그룹이 아니라 행에 걸립니다. 이메일로 묶인 인스타·틱톡 등록 건 중 필터에 맞는 행이 대표가 됩니다

운영 실측(2026-08-26) 기준 3,261행이 1,994명으로 묶입니다. 한 사람이 최대 13행까지 묶인 사례가 있습니다.

크롤 지표 매칭

sns_account_id는 폼 입력 원본이라 전체 URL · @핸들 · 맨 핸들 · 스킴 없는 호스트가 섞여 있습니다. 이 API는 저장값에서 핸들을 뽑아 표준 프로필 URL로 맞춘 뒤 PostgreSQL influencer_profile.account_link를 조회합니다.

매칭 방식인스타 기준 매칭률
저장값 그대로444 / 1,910 (23%)
정규화 후 표준 URL 2변형1,644 / 1,910 (86%)

크롤 데이터가 없으면 crawled가 false이고 지표 필드는 전부 null입니다.

틱톡은 매칭률이 낮습니다. 크롤 수집 트리거가 뒤늦게 붙어서 그 이전 등록 건에는 PostgreSQL 데이터 자체가 없습니다.

평균 지표의 기준은 플랫폼마다 다릅니다

avgViews · avgLikes · avgComments 는 플랫폼에 맞는 컬럼에서 골라 채웁니다. 어느 쪽에서 왔는지는 metricBasis 로 알 수 있습니다.

플랫폼metricBasis읽는 컬럼
인스타그램 · 유튜브REELSreels_avg_views · reels_avg_likes · reels_avg_comments
틱톡 · 네이버FLATavg_views · avg_likes · avg_comments

틱톡과 네이버는 "릴스"에 대응하는 콘텐츠 구분이 없어 크롤러가 reels_avg_* 를 채우지 않습니다. 운영 실측(2026-08-27) 기준 reels_avg_views 가 채워진 행은 인스타 107,663건인 반면 틱톡·네이버는 0건입니다. 그래서 프론트에서 플랫폼 구분 없이 릴스 필드를 읽으면 틱톡·네이버 항목이 통째로 빈칸이 됩니다.

rankingPrice 는 릴스 조회수로 산출되므로 틱톡·네이버는 항상 null 입니다. 값이 없는 것이지 0원이 아니며, 화면에서 0 이나 최저가로 표시하면 안 됩니다.

응답

성공 응답 (200 OK)

{
  "status": 200,
  "code": null,
  "message": "희망자풀 조회 성공",
  "data": {
    "items": [
      {
        "id": 3260,
        "applicantName": "김글로브",
        "contactEmail": "creator@example.com",
        "notificationPhone": "010-1234-5678",
        "snsType": "INSTAGRAM",
        "snsAccountId": "https://www.instagram.com/berryzzin?igsh=abc",
        "snsAccountLink": "https://www.instagram.com/berryzzin",
        "categories": "FASHION,BEAUTY",
        "defaultUnitPrice": "300000",
        "createdAt": "2026-08-26T12:14:16",
        "crawled": true,
        "followers": 12345,
        "avgViews": 15200.0,
        "avgLikes": 610.0,
        "avgComments": 44.0,
        "metricBasis": "REELS",
        "adjustedEngagementRate": 3.2,
        "rankingPrice": 220000,
        "duplicateCount": 3,
        "duplicateIds": [2841, 1502]
      }
    ],
    "page": 0,
    "size": 20,
    "totalElements": 1994,
    "totalPages": 100,
    "totalRowsBeforeDedup": 3264,
    "sort": "CREATED_AT",
    "direction": "desc",
    "summary": {
      "totalPeople": 1994,
      "totalRows": 3264,
      "bySnsType": {
        "FACEBOOK": 0,
        "INSTAGRAM": 1740,
        "YOUTUBE": 82,
        "TIKTOK": 55,
        "NAVER": 117
      },
      "crawled": 1663,
      "uncrawled": 331
    }
  }
}

항목 필드

필드타입설명
idLong대표 행 ID (중복 그룹 중 가장 최근 등록 건)
applicantNameString신청자명
contactEmailString협업 연락용 이메일
notificationPhoneString협업 알림용 전화번호
snsTypeStringSNS 타입
snsAccountIdString저장된 원본 입력값
snsAccountLinkString정규화된 프로필 링크
categoriesString협업 카테고리 (대문자 CSV)
defaultUnitPriceString평소 진행 단가 (신청자 입력값)
createdAtDateTime대표 행 등록일시
crawledBoolean크롤 데이터 매칭 여부. false면 아래 지표가 전부 null
followersInteger팔로워 수
avgViews · avgLikes · avgCommentsDouble평균 조회수 · 좋아요 · 댓글. 기준은 metricBasis 참고
metricBasisStringREELS(인스타·유튜브) 또는 FLAT(틱톡·네이버)
adjustedEngagementRateDouble보정 참여율
rankingPriceInteger랭킹가(원). 틱톡·네이버는 항상 null
duplicateCountInteger묶인 등록 건수 (본인 포함). 1이면 중복 없음
duplicateIdsLong[]묶인 나머지 행 ID (최신순)

페이지 필드

필드타입설명
page · sizeInteger요청한 페이지 · 크기
totalElementsLong필터·중복 제거 후 인원 수
totalPagesInteger총 페이지 수
totalRowsBeforeDedupLong중복 제거 전 원본 행 수 (필터 적용 후)
sort · directionString실제로 적용된 정렬

summary — 필터와 무관한 전체 기준

필터 칩에 붙일 숫자라 필터를 걸어도 바뀌지 않습니다. 필터 적용 후 숫자가 필요하면 totalElements 를 쓰세요.

필드타입설명
totalPeopleLong중복 제거 후 전체 인원
totalRowsLong중복 제거 전 전체 행 수
bySnsTypeObjectSNS 타입별 인원. 0명인 타입도 키가 있습니다
crawled · uncrawledLong크롤 지표 보유 여부별 인원

에러 응답

상태 코드설명
401인증 실패
403ADMIN 권한 없음

성능

전량을 메모리로 올려 중복을 묶은 뒤 필터·정렬·페이징합니다. 중복 판정 키가 저장된 sns_account_id가 아니라 거기서 뽑아낸 정규화 핸들이라 SQL로 접을 수 없기 때문입니다.

PostgreSQL 프로필도 전량 조회합니다 — summary의 크롤 인원 집계와 지표 정렬·필터가 모두 페이지 밖 사람들의 값을 필요로 합니다. 운영 실측(2026-08-27) 기준 4,506키에 217ms 이고, 키가 이만큼 많으면 플래너가 인덱스 대신 Seq Scan을 고릅니다. unnest + JOIN 으로 바꿔 인덱스를 강제하면 405ms로 오히려 느려져 그대로 두었습니다.

랭킹가는 sort=RANKING_PRICE 일 때만 전량 조회하고, 그 외에는 현재 페이지만 조회합니다.

현재 3천 행 규모라 문제없지만, 수만 행으로 늘면 정규화 핸들을 컬럼으로 저장하고 SQL 페이징으로 바꿔야 합니다.

API 테스트

On this page