Glowb Dev Docs
Main API

통합 트렌드 콘텐츠 레코드

YouTube + TikTok + Instagram 을 목업 23필드 단일 스키마로 정규화해 한 번에 내려주는 통합 API.

통합 트렌드 콘텐츠 레코드

세 플랫폼(YouTube·TikTok·Instagram)의 트렌드 콘텐츠를 하나의 "콘텐츠 레코드"(23필드) 스키마로 정규화해 한 번에 반환합니다. 수집·적재는 파이썬(sns-crawler-python), 서빙은 백엔드가 PostgreSQL 원본 테이블을 직접 읽습니다.

  • 플랫폼당 최근 perPlatform(기본 100)씩 가져와 재현가능 셔플로 섞어 내려줍니다.
  • total = 3소스 전체 레코드 수(현재 필터 기준).

HTTP 요청

GET /api/trend/records?region=KR&category=BEAUTY&perPlatform=100

Query Parameters

파라미터타입필수설명
regionString아니오지역(YouTube region / TikTok country_code). Instagram(post)은 지역 컬럼이 없어 미적용
platformString아니오YOUTUBE | TIKTOK | INSTAGRAM 단일 필터. 미지정=3개 전체
categoryString아니오분야 BEAUTY | FASHION | TRAVEL. 미지정=전체
perPlatformInteger아니오플랫폼당 최근 N건(1~500, 기본 100)

category 는 3플랫폼에 각각 적용됩니다 — YouTube=keyword_slot, TikTok=tiktok_trend_hashtag.category 조인, Instagram=분야별 한글 키워드로 캡션(caption) ILIKE 검색(YT/TikTok처럼 미리 수집된 분야가 없어 라이브 검색).

응답 (200 OK)

표준 ApiResponse 래퍼. 실제 데이터는 data.

{
  "status": 200, "code": null, "message": "조회 완료",
  "data": {
    "total": 13672,
    "counts": { "youtube": 8200, "tiktok": 3100, "instagram": 2372 },
    "returned": 300,
    "records": [
      {
        "source": "tiktok_trend", "platform": "TIKTOK",
        "record_id": "7412...", "account_pk": "beauty_kr", "account": "뷰티크리에이터",
        "cluster_id": null, "taken_at": null, "lang": "ko", "region": "KR",
        "media_type": "VIDEO", "duration_s": 23, "hashtag_n": 5,
        "audio_id": "70123...", "like_count": null, "comment_count": null,
        "share_count": null, "save_count": null, "play_count": null,
        "eng_rate": null, "delta_6h": null, "snapshot_seq": null,
        "captured_at": "2026-07-27T02:10:00Z", "status": "ACTIVE",
        "title": "여름 데일리 메이크업 #메이크업 #grwm",
        "url": "https://www.tiktok.com/@beauty_kr/video/7412...",
        "thumbnail": "https://...", "audio_title": "Catch Catch", "audio_author": "YENA"
      },
      {
        "source": "youtube_trend", "platform": "YOUTUBE",
        "record_id": "5xQI8KouLPc", "account_pk": "UC7h...", "account": "스타템픽",
        "taken_at": "2026-07-25T12:00:00Z", "lang": null, "region": "KR",
        "media_type": "SHORTS", "duration_s": 14, "hashtag_n": 2,
        "audio_id": "sjtyqmA-pH4", "like_count": 12030, "comment_count": 210,
        "share_count": null, "save_count": null, "play_count": 450050,
        "eng_rate": 0.027197, "delta_6h": 8400, "snapshot_seq": 3,
        "captured_at": "2026-07-27", "status": "public",
        "title": "여자들이 한순간에 반한 이유 #메이크업", "url": "https://www.youtube.com/watch?v=5xQI8KouLPc",
        "thumbnail": "https://i.ytimg.com/vi/5xQI8KouLPc/hqdefault.jpg"
      }
    ]
  }
}

콘텐츠 레코드 필드 (플랫폼별 채움)

=값 있음 · =파생/계산 · =해당 플랫폼 미제공(null)

필드YouTubeTikTokInstagram비고
source / platform원본 테이블 / 플랫폼
record_idvideo_iditem_idpost_id콘텐츠 id
account_pk / accountchannel_id / titleauthor_unique_id / nameaccount_id / handle
cluster_id분석 파생(수집 원천 아님)
taken_atpublished_atpublished_atTikTok trend_video 엔 게시일 없음
langdefault_audio_languagetextLanguageYT도 대부분 null
regioncountry_codeTikTok=수집 조합 국가(v.region=locationCreated 와 다름). post 엔 지역 컬럼 없음
media_typeSHORTS/VIDEOVIDEOIMAGE/VIDEO
duration_sTikTok=영상 길이(music_duration=음원 길이라 별개)
hashtag_nhashtag_n 컬럼YT/IG=제목·캡션의 # 수(서버 계산), TikTok=컬럼 값(없으면 계산)
audio_id쇼츠 사운드music_id ✅TikTok=음원 강점, IG post=음원 없음
like_count / comment_countpost_metrics ✅
share_count / save_countpost_metrics ✅YT 미제공
play_countview_countviews(post_metrics)
eng_rate(like+comment)/play 계산
delta_6h / snapshot_seqview_delta / snapshot_countYT만 롤링 델타 보유
captured_atcollected_datecollected_atcrawled_at
statusprivacyStatusACTIVE/PRIVATE/REVIEWING/REMOVEDsponsored 여부
title / url / thumbnailcaption / post_link / covercaption / post_link / ∅렌더용 확장 필드

각 플랫폼 강점: YouTube=조회수·델타, TikTok=음원, Instagram=engagement(post_metrics).

null 이 될 수 있는 필드

플랫폼마다 원천이 제공하는 값이 달라 아래 필드는 null 로 내려갈 수 있습니다. FE는 모든 지표/부가 필드를 null 허용으로 처리하세요(빈칸·-·기본값).

모든 플랫폼 공통

  • cluster_id — 분석 파생값(클러스터링 결과)이라 수집 원천에 없음 → 현재 항상 null.

구조상 항상 null (해당 플랫폼이 원천에서 제공 안 함)

플랫폼항상 null 필드이유
YouTubeshare_count, save_countYouTube API 미제공
TikToktaken_at, like_count, comment_count, share_count, save_count, play_count, eng_rate, delta_6h, snapshot_seqtiktok_trend_video 엔 게시일·지표 컬럼이 없음(Creative Center 트렌드 스냅샷이라 조회수·좋아요는 item_id 로 나중에 보강 예정)
Instagramregion, duration_s, audio_id, delta_6h, snapshot_seq, lang, thumbnailpost 엔 지역·음원 컬럼 없음, 썸네일은 v1 미파싱

조건부 null (값이 있을 때만 채움)

  • lang(YouTube) — default_audio_language 는 유튜브가 잘 안 채워 대부분 null.
  • audio_id(YouTube) — 쇼츠가 라이브러리 음원을 쓴 경우만. 오리지널 사운드·롱폼은 null.
  • lang·duration_s·status(TikTok) — 수집 시점에 원본이 비어있던 행은 null.
  • status — YouTube는 원본 privacyStatus 없으면 null(대개 public), TikTok은 ACTIVE/PRIVATE/REVIEWING/REMOVED(서버는 걸러내지 않으니 FE에서 노출 정책 결정), Instagram은 스폰서 게시물일 때만 "sponsored" 아니면 null.
  • like/comment/share/save/play_count(Instagram) — post_metrics 조인 결과라 해당 게시물 metrics 가 아직 수집 안 됐으면 null(LEFT JOIN).
  • eng_rateplay_count(재생수)가 없거나 like·comment 가 모두 없으면 null.
  • YouTube가 v3 쿼터 소진으로 YT-API fallback 수집된 행은 like_count·comment_count·lang·status 등이 null 일 수 있음.

어떤 플랫폼 소스가 통째로 비어있으면(테이블에 데이터 없음/조회 실패) 그 플랫폼 레코드는 응답에서 아예 빠집니다(필드가 null이 아니라 레코드 자체가 없음). 플랫폼별 실제 건수는 counts 로 확인하세요.

동작 상세

  • 재현가능 셔플: 반환 레코드는 현재 레코드 집합에서 유도한 시드로 셔플합니다. 데이터가 그대로면 매 요청 순서가 동일하고, 레코드가 추가/삭제/변경되면 순서가 바뀝니다(FE 캐싱·페이지 안정성 목적).
  • 데이터소스: YouTube=youtube_trend(agent PG), TikTok=tiktok_trend_video·Instagram=post(+post_metrics)(crawl PG). prod는 동일 물리 DB, test는 분리 DB(코드는 두 데이터소스로 정상 동작).
  • 부분 허용: 한 플랫폼 소스가 비어있거나 조회 실패해도 나머지는 정상 서빙(counts 에 반영).
  • DDL 없음 — 세 테이블 모두 이미 수집·존재.

Instagram 캡션 검색(category 지정 시)은 post.caption 에 인덱스가 없어 데이터가 많으면 느릴 수 있습니다(전량이 아니라 최근 perPlatform 건만 반환하도록 스코프). 성능 이슈 시 pg_trgm GIN 인덱스가 후속 옵션입니다.

API 테스트

On this page