YouTube Data API: 개발자 가이드 완벽 정리 (2026)
YouTube 콘텐츠를 프로그래밍 방식으로 검색, 목록화 및 관리하는 방법
Hypereal로 구축 시작하기
단일 API를 통해 Kling, Flux, Sora, Veo 등에 액세스하세요. 무료 크레딧으로 시작하고 수백만으로 확장하세요.
신용카드 불필요 • 10만 명 이상의 개발자 • 엔터프라이즈 지원
YouTube Data API: 개발자 가이드 완벽 정리 (2026)
YouTube Data API v3를 사용하면 YouTube의 기능을 애플리케이션에 통합할 수 있습니다. 동영상 검색, 채널 정보 조회, 재생목록 관리, 댓글 읽기 등 모든 작업을 프로그래밍 방식으로 수행할 수 있습니다.
이 가이드는 API 액세스 설정, 첫 번째 요청 보내기, 실용적인 코드 예제를 통한 공통 기능 구축까지 시작하는 데 필요한 모든 내용을 다룹니다.
시작하기
1단계: Google Cloud Project 생성
- console.cloud.google.com에 접속합니다.
- 새 프로젝트를 생성합니다 (또는 기존 프로젝트를 선택합니다).
- APIs & Services > Library로 이동합니다.
- "YouTube Data API v3"를 검색하고 활성화합니다.
2단계: API 사용자 인증 정보 생성
사용 사례에 따라 두 가지 옵션이 있습니다.
| 인증 정보 유형 | 사용 사례 | 액세스 권한 |
|---|---|---|
| API Key | 공개 데이터 (검색, 동영상 세부 정보) | 읽기 전용, 사용자 인증 없음 |
| OAuth 2.0 | 사용자 데이터 (재생목록, 구독, 업로드) | 사용자 동의하에 읽기/쓰기 가능 |
API Key 생성 방법:
- APIs & Services > Credentials로 이동합니다.
- Create Credentials > API Key를 클릭합니다.
- (선택 사항) 해당 키를 YouTube Data API로 사용 제한합니다.
OAuth 2.0 생성 방법:
- APIs & Services > Credentials로 이동합니다.
- Create Credentials > OAuth client ID를 클릭합니다.
- 동의 화면(Consent screen)을 구성합니다.
- 애플리케이션 유형(Web, Desktop 등)을 선택합니다.
- Client ID와 Client Secret을 기록해 둡니다.
3단계: 클라이언트 라이브러리 설치
# Python
pip install google-api-python-client google-auth-oauthlib
# Node.js
npm install googleapis
# Go
go get google.golang.org/api/youtube/v3
API Key 인증 (공개 데이터)
동영상 검색이나 채널 정보 확인과 같은 공개 데이터를 읽을 때는 API Key만으로 충분합니다.
Python
from googleapiclient.discovery import build
API_KEY = "YOUR_API_KEY"
youtube = build("youtube", "v3", developerKey=API_KEY)
JavaScript (Node.js)
import { google } from "googleapis";
const youtube = google.youtube({
version: "v3",
auth: "YOUR_API_KEY",
});
동영상 검색
search.list 엔드포인트는 가장 일반적으로 사용됩니다. 키워드, 채널, 위치 등으로 검색을 지원합니다.
기본 검색
def search_videos(query, max_results=10):
request = youtube.search().list(
part="snippet",
q=query,
type="video",
maxResults=max_results,
order="relevance"
)
response = request.execute()
videos = []
for item in response["items"]:
videos.append({
"title": item["snippet"]["title"],
"videoId": item["id"]["videoId"],
"channel": item["snippet"]["channelTitle"],
"published": item["snippet"]["publishedAt"],
"thumbnail": item["snippet"]["thumbnails"]["high"]["url"],
})
return videos
# 사용 예시
results = search_videos("python tutorial 2026")
for video in results:
print(f"{video['title']} - https://youtube.com/watch?v={video['videoId']}")
JavaScript 버전
async function searchVideos(query, maxResults = 10) {
const response = await youtube.search.list({
part: "snippet",
q: query,
type: "video",
maxResults: maxResults,
order: "relevance",
});
return response.data.items.map((item) => ({
title: item.snippet.title,
videoId: item.id.videoId,
channel: item.snippet.channelTitle,
published: item.snippet.publishedAt,
thumbnail: item.snippet.thumbnails.high.url,
}));
}
const results = await searchVideos("javascript tutorial 2026");
검색 파라미터
| 파라미터 | 설명 | 예시 |
|---|---|---|
q |
검색 쿼리 | "python machine learning" |
type |
리소스 유형 | "video", "channel", "playlist" |
order |
정렬 순서 | "relevance", "date", "viewCount", "rating" |
maxResults |
페이지당 결과 수 (1-50) | 25 |
publishedAfter |
날짜 필터링 | "2026-01-01T00:00:00Z" |
channelId |
특정 채널 내 검색 | "UCxxxxxxxx" |
videoDuration |
동영상 길이 필터링 | "short", "medium", "long" |
regionCode |
국가별 결과 | "US", "KR", "JP" |
relevanceLanguage |
언어 선호도 | "ko", "en" |
동영상 세부 정보 가져오기
videos.list 엔드포인트는 특정 동영상에 대한 자세한 정보를 제공합니다.
def get_video_details(video_ids):
"""하나 이상의 동영상에 대한 상세 정보를 가져옵니다."""
request = youtube.videos().list(
part="snippet,statistics,contentDetails",
id=",".join(video_ids)
)
response = request.execute()
videos = []
for item in response["items"]:
videos.append({
"title": item["snippet"]["title"],
"description": item["snippet"]["description"],
"channel": item["snippet"]["channelTitle"],
"published": item["snippet"]["publishedAt"],
"duration": item["contentDetails"]["duration"],
"views": int(item["statistics"].get("viewCount", 0)),
"likes": int(item["statistics"].get("likeCount", 0)),
"comments": int(item["statistics"].get("commentCount", 0)),
"tags": item["snippet"].get("tags", []),
})
return videos
# 사용 예시
details = get_video_details(["dQw4w9WgXcQ"])
print(f"조회수: {details[0]['views']:,}")
사용 가능한 Part
| Part | 포함 데이터 | 할당량 비용 |
|---|---|---|
snippet |
제목, 설명, 섬네일, 태그 | 2 |
statistics |
조회수, 좋아요, 댓글 수 | 2 |
contentDetails |
영상 길이, 해상도, 자막 여부 | 2 |
status |
공개 상태, 라이선스, 퍼가기 가능 여부 | 2 |
player |
임베드용 HTML | 0 |
topicDetails |
주제 카테고리 | 2 |
채널 정보 가져오기
def get_channel_info(channel_id):
request = youtube.channels().list(
part="snippet,statistics,brandingSettings",
id=channel_id
)
response = request.execute()
if not response["items"]:
return None
channel = response["items"][0]
return {
"name": channel["snippet"]["title"],
"description": channel["snippet"]["description"],
"subscribers": int(channel["statistics"].get("subscriberCount", 0)),
"totalViews": int(channel["statistics"].get("viewCount", 0)),
"videoCount": int(channel["statistics"].get("videoCount", 0)),
"thumbnail": channel["snippet"]["thumbnails"]["high"]["url"],
"customUrl": channel["snippet"].get("customUrl", ""),
}
# 사용 예시
channel = get_channel_info("UC_x5XG1OV2P6uZZ5FSM9Ttw") # Google Developers
print(f"{channel['name']}: 구독자 {channel['subscribers']:,}명")
재생목록 작업
채널의 재생목록 목록 가져오기
def get_channel_playlists(channel_id, max_results=25):
request = youtube.playlists().list(
part="snippet,contentDetails",
channelId=channel_id,
maxResults=max_results
)
response = request.execute()
return [{
"title": item["snippet"]["title"],
"playlistId": item["id"],
"videoCount": item["contentDetails"]["itemCount"],
"description": item["snippet"]["description"],
} for item in response["items"]]
재생목록 내 동영상 가져오기
def get_playlist_videos(playlist_id):
videos = []
next_page_token = None
while True:
request = youtube.playlistItems().list(
part="snippet",
playlistId=playlist_id,
maxResults=50,
pageToken=next_page_token
)
response = request.execute()
for item in response["items"]:
videos.append({
"title": item["snippet"]["title"],
"videoId": item["snippet"]["resourceId"]["videoId"],
"position": item["snippet"]["position"],
})
next_page_token = response.get("nextPageToken")
if not next_page_token:
break
return videos
# 사용 예시: 재생목록의 모든 동영상 가져오기
videos = get_playlist_videos("PLRqwX-V7Uu6ZiZxtDDRCi6uhfTH4FilpH")
print(f"재생목록에서 {len(videos)}개의 동영상을 찾았습니다.")
댓글 읽기
def get_video_comments(video_id, max_results=20):
request = youtube.commentThreads().list(
part="snippet",
videoId=video_id,
maxResults=max_results,
order="relevance",
textFormat="plainText"
)
response = request.execute()
comments = []
for item in response["items"]:
comment = item["snippet"]["topLevelComment"]["snippet"]
comments.append({
"author": comment["authorDisplayName"],
"text": comment["textDisplay"],
"likes": comment["likeCount"],
"published": comment["publishedAt"],
})
return comments
# 사용 예시
comments = get_video_comments("dQw4w9WgXcQ")
for c in comments[:5]:
print(f"{c['author']}: {c['text'][:100]}")
페이지네이션 (Pagination)
YouTube API 응답은 페이지 단위로 제공됩니다. 추가 페이지를 가져오려면 nextPageToken을 사용하세요.
def search_all_videos(query, max_total=100):
"""자동 페이지네이션을 포함한 검색."""
all_results = []
next_page_token = None
while len(all_results) < max_total:
request = youtube.search().list(
part="snippet",
q=query,
type="video",
maxResults=min(50, max_total - len(all_results)),
pageToken=next_page_token
)
response = request.execute()
for item in response["items"]:
all_results.append({
"title": item["snippet"]["title"],
"videoId": item["id"]["videoId"],
})
next_page_token = response.get("nextPageToken")
if not next_page_token:
break
return all_results
할당량 관리 (Quota Management)
YouTube Data API는 할당량 시스템을 사용합니다. 기본적으로 하루 10,000 유닛이 무료로 제공됩니다.
작업별 할당량 비용
| 작업 | 할당량 비용 |
|---|---|
search.list |
100 |
videos.list |
part당 1 |
channels.list |
part당 1 |
playlists.list |
part당 1 |
playlistItems.list |
part당 1 |
commentThreads.list |
1 |
videos.insert (업로드) |
1,600 |
videos.update |
50 |
videos.delete |
50 |
할당량 최적화 팁
- 검색 호출 최소화 --
search.list는 100 유닛이 소모됩니다. 결과를 캐싱하세요. - 동영상 ID 일괄 처리 --
videos.list는 한 번의 요청에 최대 50개의 ID를 수용할 수 있습니다. - 필요한 part만 요청 -- 각
part는 비용을 증가시킵니다. fields파라미터 사용 -- 응답 크기를 줄입니다 (할당량이 줄지는 않지만 요청 속도가 빨라집니다).
# 효율적인 예: 여러 동영상에 대한 일괄 요청
request = youtube.videos().list(
part="statistics", # 필요한 정보만 요청
id="id1,id2,id3,id4,id5", # 최대 50개까지 ID 묶기
fields="items(id,statistics/viewCount)" # 필요한 필드만 반환
)
할당량 증설 요청
하루 10,000 유닛으로 충분하지 않은 경우:
- Google Cloud Console > APIs & Services > YouTube Data API v3로 이동합니다.
- Quotas 탭을 클릭한 후 Request Quota Increase를 클릭합니다.
- 사용 사례를 설명하는 양식을 작성합니다.
- Google은 보통 영업일 기준 수일 내에 답변을 줍니다.
에러 핸들링
from googleapiclient.errors import HttpError
def safe_search(query):
try:
request = youtube.search().list(
part="snippet",
q=query,
type="video",
maxResults=10
)
return request.execute()
except HttpError as e:
status = e.resp.status
if status == 403:
error_reason = e.error_details[0]["reason"] if e.error_details else ""
if error_reason == "quotaExceeded":
print("일일 할당량을 초과했습니다. 내일 다시 시도하세요.")
else:
print(f"접근 거부: {error_reason}")
elif status == 400:
print(f"잘못된 요청: {e}")
elif status == 404:
print("리소스를 찾을 수 없습니다.")
else:
print(f"HTTP {status}: {e}")
return None
일반적인 사용 사례
동영상 대시보드 구축
def get_channel_dashboard(channel_id):
"""YouTube 채널용 전체 대시보드 데이터를 가져옵니다."""
# 채널 정보 가져오기
channel = get_channel_info(channel_id)
# 최근 업로드 목록 가져오기 (업로드 재생목록 ID = "UU" + channel_id[2:])
uploads_playlist_id = "UU" + channel_id[2:]
recent_videos = get_playlist_videos(uploads_playlist_id)[:10]
# 최근 업로드된 동영상의 세부 정보 가져오기
video_ids = [v["videoId"] for v in recent_videos]
video_details = get_video_details(video_ids)
return {
"channel": channel,
"recentVideos": video_details,
"totalViews": sum(v["views"] for v in video_details),
"avgViews": sum(v["views"] for v in video_details) // len(video_details),
}
동영상 성과 추적
import json
from datetime import datetime
def track_video_stats(video_id, output_file="stats.json"):
"""트렌드 분석을 위해 동영상 통계를 기록합니다."""
details = get_video_details([video_id])[0]
entry = {
"timestamp": datetime.now().isoformat(),
"views": details["views"],
"likes": details["likes"],
"comments": details["comments"],
}
# JSON 파일에 추가
try:
with open(output_file, "r") as f:
data = json.load(f)
except FileNotFoundError:
data = []
data.append(entry)
with open(output_file, "w") as f:
json.dump(data, f, indent=2)
print(f"기록됨: 조회수 {entry['views']:,}, 좋아요 {entry['likes']:,}")
속도 제한 및 모범 사례 (Best Practices)
| 모범 사례 | 설명 |
|---|---|
| 응답 캐싱 | 불필요한 API 호출을 피하기 위해 검색 결과를 로컬에 저장하세요. |
| ETag 사용 | 조건부 요청을 위해 If-None-Match 헤더를 포함하세요. |
| 일괄 요청 (Batching) | 여러 동영상 ID를 단일 videos.list 호출로 결합하세요. |
| 현명한 페이지네이션 | 필요한 경우에만 추가 페이지를 가져오세요. |
| 할당량 사용량 모니터링 | Google Cloud Console의 할당량 대시보드를 매일 확인하세요. |
| 변경 알림을 위한 Webhook | 실시간 업데이트를 위해 YouTube Push Notification을 고려하세요. |
결론
YouTube Data API는 강력하고 문서화가 잘 되어 있지만, 할당량 관리가 무엇보다 중요합니다. 캐싱, 일괄 처리, 선택적 part 요청을 통해 API 호출을 최소화하도록 애플리케이션을 설계하세요.
동영상 관련 애플리케이션을 개발하는 개발자에게 YouTube Data API는 AI 동영상 생성 도구와 함께 사용하면 시너지가 좋습니다. Hypereal AI는 AI 동영상, 말하는 아바타, 이미지 콘텐츠를 생성할 수 있는 API를 제공하며, 이를 YouTube에 업로드하거나 애플리케이션에서 YouTube 콘텐츠와 함께 활용할 수 있습니다.
