YouTube Data API: Complete Developer Guide (2026)
How to search, list, and manage YouTube content programmatically
Start Building with Hypereal
Access Kling, Flux, Sora, Veo & more through a single API. Free credits to start, scale to millions.
No credit card required • 100k+ developers • Enterprise ready
YouTube Data API: Complete Developer Guide (2026)
The YouTube Data API v3 lets you integrate YouTube functionality into your application. You can search for videos, retrieve channel information, manage playlists, read comments, and more -- all programmatically.
This guide covers everything you need to get started: setting up API access, making your first requests, and building common features with practical code examples.
Getting Started
Step 1: Create a Google Cloud Project
- Go to console.cloud.google.com
- Create a new project (or select an existing one)
- Navigate to APIs & Services > Library
- Search for "YouTube Data API v3" and enable it
Step 2: Create API Credentials
You have two options depending on your use case:
| Credential Type | Use Case | Access |
|---|---|---|
| API Key | Public data (search, video details) | Read-only, no user auth |
| OAuth 2.0 | User data (playlists, subscriptions, uploads) | Read/write with user consent |
For an API Key:
- Go to APIs & Services > Credentials
- Click Create Credentials > API Key
- (Optional) Restrict the key to the YouTube Data API
For OAuth 2.0:
- Go to APIs & Services > Credentials
- Click Create Credentials > OAuth client ID
- Configure the consent screen
- Choose your application type (Web, Desktop, etc.)
- Note your Client ID and Client Secret
Step 3: Install a Client Library
# 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 Authentication (Public Data)
For reading public data like searching videos or getting channel info, an API key is sufficient:
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",
});
Searching for Videos
The search.list endpoint is the most commonly used. It supports searching by keyword, channel, location, and more.
Basic Search
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
# Usage
results = search_videos("python tutorial 2026")
for video in results:
print(f"{video['title']} - https://youtube.com/watch?v={video['videoId']}")
JavaScript Version
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");
Search Parameters
| Parameter | Description | Example |
|---|---|---|
q |
Search query | "python machine learning" |
type |
Resource type | "video", "channel", "playlist" |
order |
Sort order | "relevance", "date", "viewCount", "rating" |
maxResults |
Results per page (1-50) | 25 |
publishedAfter |
Filter by date | "2026-01-01T00:00:00Z" |
channelId |
Search within a channel | "UCxxxxxxxx" |
videoDuration |
Filter by length | "short", "medium", "long" |
regionCode |
Regional results | "US", "GB", "JP" |
relevanceLanguage |
Language preference | "en", "es" |
Getting Video Details
The videos.list endpoint provides detailed information about specific videos:
def get_video_details(video_ids):
"""Get detailed info for one or more videos."""
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
# Usage
details = get_video_details(["dQw4w9WgXcQ"])
print(f"Views: {details[0]['views']:,}")
Available Parts
| Part | Data Included | Quota Cost |
|---|---|---|
snippet |
Title, description, thumbnails, tags | 2 |
statistics |
View count, likes, comments | 2 |
contentDetails |
Duration, definition, captions | 2 |
status |
Privacy, license, embeddable | 2 |
player |
Embed HTML | 0 |
topicDetails |
Topic categories | 2 |
Getting Channel Information
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", ""),
}
# Usage
channel = get_channel_info("UC_x5XG1OV2P6uZZ5FSM9Ttw") # Google Developers
print(f"{channel['name']}: {channel['subscribers']:,} subscribers")
Working with Playlists
List Playlists for a Channel
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"]]
Get Videos in a Playlist
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
# Usage: Get all videos from a playlist
videos = get_playlist_videos("PLRqwX-V7Uu6ZiZxtDDRCi6uhfTH4FilpH")
print(f"Found {len(videos)} videos in playlist")
Reading Comments
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
# Usage
comments = get_video_comments("dQw4w9WgXcQ")
for c in comments[:5]:
print(f"{c['author']}: {c['text'][:100]}")
Pagination
YouTube API responses are paginated. Use nextPageToken to fetch additional pages:
def search_all_videos(query, max_total=100):
"""Search with automatic pagination."""
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
The YouTube Data API uses a quota system. You start with 10,000 units per day (free tier).
Quota Costs by Operation
| Operation | Quota Cost |
|---|---|
search.list |
100 |
videos.list |
1 per part |
channels.list |
1 per part |
playlists.list |
1 per part |
playlistItems.list |
1 per part |
commentThreads.list |
1 |
videos.insert (upload) |
1,600 |
videos.update |
50 |
videos.delete |
50 |
Quota Optimization Tips
- Minimize search calls --
search.listcosts 100 units. Cache results. - Batch video IDs --
videos.listaccepts up to 50 IDs in one request. - Request only needed parts -- each
partadds to the cost. - Use
fieldsparameter -- reduce response size (does not reduce quota but speeds up requests).
# Efficient: batch request for multiple videos
request = youtube.videos().list(
part="statistics", # Only request what you need
id="id1,id2,id3,id4,id5", # Batch up to 50 IDs
fields="items(id,statistics/viewCount)" # Only return needed fields
)
Requesting Higher Quota
If 10,000 units per day is not enough:
- Go to Google Cloud Console > APIs & Services > YouTube Data API v3
- Click Quotas and then Request Quota Increase
- Fill out the form explaining your use case
- Google typically responds within a few business days
Error Handling
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("Daily quota exceeded. Try again tomorrow.")
else:
print(f"Forbidden: {error_reason}")
elif status == 400:
print(f"Bad request: {e}")
elif status == 404:
print("Resource not found")
else:
print(f"HTTP {status}: {e}")
return None
Common Use Cases
Build a Video Dashboard
def get_channel_dashboard(channel_id):
"""Get a complete dashboard for a YouTube channel."""
# Get channel info
channel = get_channel_info(channel_id)
# Get recent uploads (uploads playlist = "UU" + channel_id[2:])
uploads_playlist_id = "UU" + channel_id[2:]
recent_videos = get_playlist_videos(uploads_playlist_id)[:10]
# Get video details for recent uploads
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),
}
Track Video Performance Over Time
import json
from datetime import datetime
def track_video_stats(video_id, output_file="stats.json"):
"""Record video stats for trend analysis."""
details = get_video_details([video_id])[0]
entry = {
"timestamp": datetime.now().isoformat(),
"views": details["views"],
"likes": details["likes"],
"comments": details["comments"],
}
# Append to JSON file
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"Recorded: {entry['views']:,} views, {entry['likes']:,} likes")
Rate Limits and Best Practices
| Best Practice | Description |
|---|---|
| Cache responses | Store search results locally to avoid redundant API calls |
| Use ETags | Include If-None-Match header for conditional requests |
| Batch requests | Combine multiple video IDs into single videos.list calls |
| Handle pagination wisely | Only fetch additional pages when needed |
| Monitor quota usage | Check the Google Cloud Console quota dashboard daily |
| Use webhooks for changes | Consider YouTube Push Notifications for real-time updates |
Conclusion
The YouTube Data API is powerful and well-documented, but quota management is critical. Design your application to minimize API calls through caching, batching, and selective part requests.
For developers building video-related applications, the YouTube Data API pairs well with AI video generation tools. Hypereal AI offers APIs for generating AI videos, talking avatars, and image content that you can upload to YouTube or use alongside YouTube content in your application.
Related Articles
Start Building Today
Get 35 free credits on signup. No credit card required. Generate your first image in under 5 minutes.
