Design & media

YouTube

Search YouTube data and manage account resources through Data API v3 with managed OAuth.

What it does

Access YouTube Data API v3 through a proxy that injects OAuth credentials for a connected Google account. Search videos, channels, and playlists; inspect video and channel data; manage playlists and subscriptions; list comments; and rate videos. Use the CLI, direct API requests, or Python, and select a connection explicitly when multiple accounts are linked.

When to use it

  • Search videos by date, duration, channel, or popularity
  • Inspect channel and video statistics
  • Create and maintain YouTube playlists
  • Review subscriptions and recent 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:

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key
  4. 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 Videos, Channels, or Playlists

GET /youtube/youtube/v3/search

Query parameters:

  • part - Required: snippet
  • q - Search query
  • type - Filter by type: video, channel, playlist
  • maxResults - Results per page (1-50, default 5)
  • order - Sort order: date, rating, relevance, title, viewCount
  • publishedAfter - Filter by publish date (RFC 3339)
  • publishedBefore - Filter by publish date (RFC 3339)
  • channelId - Filter by channel
  • videoDuration - 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 info
  • statistics - View count, likes, comments
  • contentDetails - Duration, dimension, definition
  • status - Upload status, privacy status
  • player - 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 /youtube/youtube/v3/videos?part=snippet,statistics&chart=mostPopular&regionCode=US&maxResults=10

Example:

maton youtube video list --region US --limit 10

Get Video Categories

GET /youtube/youtube/v3/videoCategories?part=snippet&regionCode=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) or UU (uploads)
  • Use pageToken for pagination through large result sets
  • The part parameter 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 -g when URLs contain brackets (fields[], sort[], records[]) to disable glob parsing
  • IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.

Error Handling

StatusMeaning
400Missing YouTube connection or invalid request
401Invalid or missing Maton API key
403Forbidden - quota exceeded or insufficient permissions
404Video, channel, or playlist not found
429Rate limited (10 req/sec per account)
4xx/5xxPassthrough error from YouTube API

Troubleshooting: API Key Issues

CLI:

  1. Check your auth state:
maton whoami
  1. Verify the API key is valid by listing connections:
maton connection list

Manual:

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. 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

  1. 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

How does authentication work?
Requests use a MATON_API_KEY, while the proxy injects the OAuth token for the connected YouTube account. Connections can be created, listed, viewed, selected, and deleted.
Which YouTube resources can it read or manage?
It covers videos, channels, playlists and playlist items, subscriptions, comments, and captions within the connected account. Documented operations include search, detail retrieval, playlist management, subscription management, comment listing, and video ratings.
Are write operations performed automatically?
No. Every create, update, or delete operation requires explicit user approval after confirming the target resource and intended effect.

Related skills

Manage Google Tasks task lists and tasks through managed OAuth, CLI commands, or API calls.

252 installs10 stars

Query Google Ads accounts and performance data with GAQL through managed OAuth.

261 installs20 stars

Create, read, and edit Google Docs through managed OAuth and proxied Docs API endpoints.

278 installs8 stars

Read and manage Google Merchant Center resources through v1 APIs with managed OAuth and approval-gated writes.

231 installs5 stars

Read and manage Outlook mail, folders, calendars, and contacts through Microsoft Graph.

771 installs46 stars

Access and manage GitHub resources through the REST API with managed OAuth connections.

595 installs47 stars