通过托管 OAuth 连接 Google Tasks,统一 API 完成任务列表与任务的读写管理。
设计与多媒体
YouTube
通过托管 OAuth 代理访问 YouTube Data API v3,搜索与管理视频、播放列表、频道、订阅和评论。
它能做什么
通过托管 OAuth 代理调用 YouTube Data API v3,访问令牌由代理自动注入。可搜索视频、频道和播放列表,获取视频与频道详情,创建、更新和删除播放列表,对视频进行点赞或点踩,订阅或退订频道,并列出视频评论。支持为每个 Google OAuth 连接单独管理,并在请求中按需指定。所有写入操作在执行前都需要用户明确确认。
什么时候用它
- 按关键词搜索 YouTube 视频、频道或播放列表
- 查询视频元数据、统计信息、分类与热门榜单
- 创建、更新或删除播放列表,并添加或移除其中的视频
- 管理频道订阅,列出视频评论
技能文档
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 账号吗?
- 可以。每个 Google OAuth 连接都有独立的连接 ID,可在 CLI 上使用 --connection,或在原生 API 请求中通过 Maton-Connection 请求头来指定要使用的账号。
相关技能
通过托管 OAuth,使用 GAQL 查询 Google Ads 广告系列、关键词和效果数据。
通过托管 OAuth 调用 Google Docs API,实现文档创建、读写与样式管理。
通过托管 OAuth 连接,读写 Google Merchant Center 的商品、库存、促销与账户数据。
通过 Microsoft Graph 接入 Outlook,读取、发送、管理邮件、文件夹、日历事件和联系人,OAuth 由平台托管。
通过托管 OAuth 接入 GitHub REST API,覆盖仓库、Issue、PR、Commit、分支与用户等接口。