Access YouTube Analytics reports and manage analytics groups via managed OAuth, proxied through Maton.
Design & media
YouTube
Try itSearch, read, and manage YouTube videos, playlists, channels, subscriptions, and comments via managed OAuth.
What it does
Access the YouTube Data API v3 through a managed OAuth proxy that injects tokens automatically. Search videos, channels, and playlists; retrieve video and channel details; create, update, and delete playlists; rate videos; subscribe and unsubscribe; and list video comments. Multiple Google OAuth connections can be managed and addressed individually per request. All write operations require explicit user confirmation before execution.
When to use it
- Searching YouTube videos, channels, or playlists by keyword
- Looking up video metadata, statistics, categories, or trending lists
- Creating, updating, or deleting playlists and adding or removing videos
- Subscribing to channels and listing video comments
The skill document
YouTube
Access the YouTube Data API v3 with managed OAuth authentication. Search videos, manage playlists, access channel information, and interact with comments and subscriptions.
Quick Start
CLI:
maton youtube search videos 'coding tutorial' --limit 10
maton api '/youtube/youtube/v3/search?part=snippet&q=coding+tutorial&type=video&maxResults=10'
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/youtube/youtube/v3/search?part=snippet&q=coding+tutorial&type=video&maxResults=10')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://api.maton.ai/youtube/{native-api-path}
Maton proxies requests to www.googleapis.com and automatically injects your OAuth token.
Installation
NPM:
npm install -g @maton/cli
Homebrew:
brew install maton-ai/cli/maton
Authentication
CLI:
maton login # Opens browser for API key
maton login --interactive # Skip browser, paste API key directly
maton whoami # Show current auth state
Manual:
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
- Set your API key as
MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Connection Management
Manage your Google OAuth connections at https://api.maton.ai.
List Connections
CLI:
maton connection list youtube --status ACTIVE
maton api -X GET /connections -f app=youtube -f status=ACTIVE
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=youtube&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
CLI:
maton connection create youtube
maton api /connections -f app=youtube
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'youtube'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
CLI:
maton connection view {connection_id}
maton api /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2025-12-08T07:20:53.488460Z",
"last_updated_time": "2026-01-31T20:03:32.593153Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "youtube",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
CLI:
maton connection delete {connection_id}
maton api -X DELETE /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple YouTube connections, specify which one to use:
CLI:
maton youtube channel mine --connection {connection_id}
maton api '/youtube/youtube/v3/channels?part=snippet&mine=true' --connection {connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/youtube/youtube/v3/channels?part=snippet&mine=true')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always specify the connection to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to videos, channels, playlists, comments, and captions within the connected YouTube account.
- All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
API Reference
Search
Search Videos, Channels, or Playlists
GET /youtube/youtube/v3/search
Query parameters:
part- Required:snippetq- Search querytype- Filter by type:video,channel,playlistmaxResults- Results per page (1-50, default 5)order- Sort order:date,rating,relevance,title,viewCountpublishedAfter- Filter by publish date (RFC 3339)publishedBefore- Filter by publish date (RFC 3339)channelId- Filter by channelvideoDuration-short(<4min),medium(4-20min),long(>20min)pageToken- Pagination token
Example:
maton youtube search videos 'machine learning' --limit 10 --order viewCount
maton youtube search channels 'rob pike'
maton youtube search playlists 'study music'
Videos
Get Video Details
GET /youtube/youtube/v3/videos?part=snippet,statistics,contentDetails&id=dQw4w9WgXcQ
Parts available:
snippet- Title, description, thumbnails, channel infostatistics- View count, likes, commentscontentDetails- Duration, dimension, definitionstatus- Upload status, privacy statusplayer- Embedded player HTML
Example:
maton youtube video view dQw4w9WgXcQ
Get My Videos (Uploaded)
GET /youtube/youtube/v3/search?part=snippet&forMine=true&type=video&order=viewCount&maxResults=25
Example:
maton youtube search mine --order viewCount --limit 25
Rate Video (Like/Dislike)
POST /youtube/youtube/v3/videos/rate?id=dQw4w9WgXcQ&rating=like
Rating values: like, dislike, none
Example:
maton youtube video rate dQw4w9WgXcQ --rating like
Get Trending Videos
GET /youtube/youtube/v3/videos?part=snippet,statistics&chart=mostPopular®ionCode=US&maxResults=10
Example:
maton youtube video list --region US --limit 10
Get Video Categories
GET /youtube/youtube/v3/videoCategories?part=snippet®ionCode=US
Example:
maton youtube video-category list --region US
Channels
Get Channel Details
GET /youtube/youtube/v3/channels?part=snippet,statistics,contentDetails&id=UCBJycsmduvYEL83R_U4JriQ
Example:
maton youtube channel view UCBJycsmduvYEL83R_U4JriQ
Get My Channel
GET /youtube/youtube/v3/channels?part=snippet,statistics,contentDetails&mine=true
Example:
maton youtube channel mine
Response:
{
"items": [
{
"id": "UCxyz123",
"snippet": {
"title": "My Channel",
"description": "Channel description",
"customUrl": "@mychannel",
"publishedAt": "2020-01-01T00:00:00Z",
"thumbnails": {...}
},
"statistics": {
"viewCount": "1000000",
"subscriberCount": "50000",
"videoCount": "100"
},
"contentDetails": {
"relatedPlaylists": {
"uploads": "UUxyz123"
}
}
}
]
}
Get Channel by Username
GET /youtube/youtube/v3/channels?part=snippet,statistics&forUsername=GoogleDevelopers
Example:
maton youtube channel view --username GoogleDevelopers
To look up by @handle instead, use maton youtube channel view --handle GoogleDevelopers.
Playlists
List My Playlists
GET /youtube/youtube/v3/playlists?part=snippet,contentDetails&mine=true&maxResults=25
Example:
maton youtube playlist list --limit 25
Get Playlist
GET /youtube/youtube/v3/playlists?part=snippet,contentDetails&id={playlistId}
Example:
maton youtube playlist view {playlistId}
Create Playlist
POST /youtube/youtube/v3/playlists?part=snippet,status
Content-Type: application/json
{
"snippet": {
"title": "My New Playlist",
"description": "A collection of videos",
"defaultLanguage": "en"
},
"status": {
"privacyStatus": "private"
}
}
Privacy values: public, private, unlisted
Example:
maton youtube playlist create --title 'My New Playlist' --description 'A collection of videos' --privacy private
Update Playlist
PUT /youtube/youtube/v3/playlists?part=snippet,status
Content-Type: application/json
{
"id": "PLxyz123",
"snippet": {
"title": "Updated Playlist Title",
"description": "Updated description"
},
"status": {
"privacyStatus": "public"
}
}
Example:
maton youtube playlist update PLxyz123 --title 'Updated Playlist Title' --description 'Updated description' --privacy public
Delete Playlist
DELETE /youtube/youtube/v3/playlists?id=PLxyz123
Example:
maton youtube playlist delete PLxyz123
Playlist Items
List Playlist Items
GET /youtube/youtube/v3/playlistItems?part=snippet,contentDetails&playlistId={playlistId}&maxResults=50
Example:
maton youtube playlist items {playlistId} --limit 50
Add Video to Playlist
POST /youtube/youtube/v3/playlistItems?part=snippet
Content-Type: application/json
{
"snippet": {
"playlistId": "PLxyz123",
"resourceId": {
"kind": "youtube#video",
"videoId": "abc123xyz"
},
"position": 0
}
}
Example:
maton youtube playlist add-video --playlist PLxyz123 --video abc123xyz --position 0
Remove from Playlist
DELETE /youtube/youtube/v3/playlistItems?id=UEx5dGVzdAAA
Example:
maton youtube playlist remove-video UEx5dGVzdAAA
The argument is the playlistItem ID (from maton youtube playlist items {playlistId}), not the video ID.
Subscriptions
List My Subscriptions
GET /youtube/youtube/v3/subscriptions?part=snippet&mine=true&maxResults=50
Example:
maton youtube subscription list --limit 50
Check Subscription to Channel
GET /youtube/youtube/v3/subscriptions?part=snippet&mine=true&forChannelId={channelId}
Example:
maton youtube subscription list --for-channel {channelId}
The response is empty when no subscription exists.
Subscribe to Channel
POST /youtube/youtube/v3/subscriptions?part=snippet
Content-Type: application/json
{
"snippet": {
"resourceId": {
"kind": "youtube#channel",
"channelId": "UCxyz123"
}
}
}
Example:
maton youtube subscription create --channel UCxyz123
Unsubscribe
DELETE /youtube/youtube/v3/subscriptions?id={subscriptionId}
Example:
maton youtube subscription delete {subscriptionId}
The argument is the subscription ID (from maton youtube subscription list), not the channel ID.
Comments
List Video Comments
GET /youtube/youtube/v3/commentThreads?part=snippet,replies&videoId={videoId}&order=time&maxResults=100
Example:
maton youtube comment list --video {videoId} --order time --limit 100
Add Comment to Video
POST /youtube/youtube/v3/commentThreads?part=snippet
Content-Type: application/json
{
"snippet": {
"videoId": "{videoId}",
"topLevelComment": {
"snippet": {
"textOriginal": "Great video!"
}
}
}
}
Example:
maton youtube comment create --video {videoId} --text 'Great video!'
Reply to Comment
POST /youtube/youtube/v3/comments?part=snippet
Content-Type: application/json
{
"snippet": {
"parentId": "{commentId}",
"textOriginal": "Thanks for your comment!"
}
}
Example:
maton youtube comment create --parent {commentId} --text 'Thanks for your comment!'
Delete Comment
DELETE /youtube/youtube/v3/comments?id={commentId}
Example:
maton youtube comment delete {commentId}
Pagination
YouTube uses cursor-based pagination via pageToken. The CLI automatically paginates with --paginate.
Example:
maton youtube playlist items {playlistId} --paginate
Code Examples
CLI
# Search videos as JSON (default format)
maton youtube search videos 'tutorial' --limit 10
# Filter with jq — e.g., extract just video IDs and titles
# Note: --jq requires --json
maton youtube search videos 'tutorial' --limit 10 \
--json --jq '.items[] | {id: .id.videoId, title: .snippet.title}'
# List your playlists and extract titles only
maton youtube playlist list --json --jq '.items[].snippet.title'
JavaScript
const headers = {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
};
// Search videos
const results = await fetch(
'https://api.maton.ai/youtube/youtube/v3/search?part=snippet&q=tutorial&type=video&maxResults=10',
{ headers }
).then(r => r.json());
// Get video details
const video = await fetch(
'https://api.maton.ai/youtube/youtube/v3/videos?part=snippet,statistics&id=dQw4w9WgXcQ',
{ headers }
).then(r => r.json());
// Create playlist
await fetch(
'https://api.maton.ai/youtube/youtube/v3/playlists?part=snippet,status',
{
method: 'POST',
headers: { ...headers, 'Content-Type': 'application/json' },
body: JSON.stringify({
snippet: { title: 'My Playlist', description: 'Videos I like' },
status: { privacyStatus: 'private' }
})
}
);
Python
import os
import requests
headers = {'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
# Search videos
results = requests.get(
'https://api.maton.ai/youtube/youtube/v3/search',
headers=headers,
params={'part': 'snippet', 'q': 'tutorial', 'type': 'video', 'maxResults': 10}
).json()
# Get video details
video = requests.get(
'https://api.maton.ai/youtube/youtube/v3/videos',
headers=headers,
params={'part': 'snippet,statistics', 'id': 'dQw4w9WgXcQ'}
).json()
# Create playlist
response = requests.post(
'https://api.maton.ai/youtube/youtube/v3/playlists?part=snippet,status',
headers=headers,
json={
'snippet': {'title': 'My Playlist', 'description': 'Videos I like'},
'status': {'privacyStatus': 'private'}
}
)
Notes
- Video IDs are 11 characters (e.g.,
dQw4w9WgXcQ) - Channel IDs start with
UC(e.g.,UCxyz123) - Playlist IDs start with
PL(user) orUU(uploads) - Use
pageTokenfor pagination through large result sets - The
partparameter is required and determines what data is returned - Quota costs vary by endpoint - search is expensive (100 units), reads are cheap (1 unit)
- Some write operations require channel verification
- IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets (fields[],sort[],records[]) to disable glob parsing - IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.
Error Handling
| Status | Meaning |
|---|---|
| 400 | Missing YouTube connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 403 | Forbidden - quota exceeded or insufficient permissions |
| 404 | Video, channel, or playlist not found |
| 429 | Rate limited (10 req/sec per account) |
| 4xx/5xx | Passthrough error from YouTube API |
Troubleshooting: API Key Issues
CLI:
- Check your auth state:
maton whoami
- Verify the API key is valid by listing connections:
maton connection list
Manual:
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
- Ensure your URL path starts with
youtube. For example:
- Correct:
https://api.maton.ai/youtube/youtube/v3/search - Incorrect:
https://api.maton.ai/v3/search
Resources
Questions people ask
- Can multiple YouTube accounts be used?
- Yes. Each Google OAuth connection has its own connection ID, and you can target a specific account per request by passing --connection on the CLI or the Maton-Connection header in raw API calls.
Related skills
Schedule bulk YouTube Analytics jobs and download daily channel and playlist reports as CSV through managed OAuth.
YouTube (youtube.com). Use this skill for ANY YouTube request — reading, creating, updating, and deleting data. Whenever a task involves YouTube, use this skill instead of calling the API directly.
Connect to Google Search Console via a managed OAuth proxy to query search analytics, manage sitemaps, and inspect site performance.
Connect to Google Tasks with managed OAuth to read and manage task lists and tasks via a unified API.
Access the Google Docs API with managed OAuth to create, read, and modify documents and formatting.