YouTube
YouTube Data API integration with managed OAuth. Search videos, manage playlists, access channel data, and interact with comments. Use this skill when users want to interact with YouTube. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
技能说明
name: youtube description: | YouTube Data API integration with managed OAuth. Search videos, manage playlists, access channel data, and interact with comments. Use this skill when users want to interact with YouTube. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). compatibility: Requires network access and valid Maton API key metadata: author: maton version: "1.0" clawdbot: emoji: 🧠 requires: env: - MATON_API_KEY
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
如何使用「YouTube」?
- 打开小龙虾AI(Web 或 iOS App)
- 点击上方「立即使用」按钮,或在对话框中输入任务描述
- 小龙虾AI 会自动匹配并调用「YouTube」技能完成任务
- 结果即时呈现,支持继续对话优化