Install
openclaw skills install @scavio-ai/youtube-data-apiSearch YouTube and retrieve videos, shorts, comments, transcripts, streams, and channel data as structured JSON. 15 endpoints across video and channel surfaces.
openclaw skills install @scavio-ai/youtube-data-apiSearch YouTube and retrieve videos, shorts, search suggestions, video metadata, comments, transcripts, related videos, download streams, and full channel data (info, videos, shorts, community posts). All endpoints return structured JSON.
Use this skill when the user asks to:
Get a free API key at scavio.dev (50 free credits to get started, no card required):
export SCAVIO_API_KEY=sk_live_your_key
An agent running this skill without SCAVIO_API_KEY set will get 401 on every
call below. The whole path from nothing to a working key is self-serve:
When the balance runs out the API answers 402 with a JSON body carrying
billing_url. Topping up needs no code change - the same key keeps working.
The smallest purchase is 2,500 credits for $25, and monthly plans work out
cheaper per credit if the usage is steady rather than one-off.
Every request is a POST with a JSON body and:
Authorization: Bearer $SCAVIO_API_KEY
Base URL: https://api.scavio.dev. All paths are under /api/v1/youtube.
| Endpoint | Credits | Description |
|---|---|---|
POST /api/v1/youtube/search | 2 | Search videos (and channels/playlists) |
POST /api/v1/youtube/shorts | 2 | Search Shorts |
POST /api/v1/youtube/suggestions | 1 | Search autocomplete suggestions |
POST /api/v1/youtube/video | 1 | Full video metadata and captions list |
POST /api/v1/youtube/comments | 1 | Top-level comments for a video |
POST /api/v1/youtube/comments/replies | 1 | Replies to a specific comment |
POST /api/v1/youtube/transcript | 8 | Full transcript or timed subtitles |
POST /api/v1/youtube/related | 1 | Videos related to a video |
POST /api/v1/youtube/streams | 3 | Direct playable/downloadable stream URLs |
| Endpoint | Credits | Description |
|---|---|---|
POST /api/v1/youtube/channel/search | 1 | Search channels |
POST /api/v1/youtube/channel | 1 | Full channel info |
POST /api/v1/youtube/channel/videos | 1 | A channel's videos |
POST /api/v1/youtube/channel/shorts | 1 | A channel's Shorts |
POST /api/v1/youtube/channel/community | 1 | A channel's community posts |
POST /api/v1/youtube/channel/resolve | 1 | Resolve a handle or URL to a channel ID |
POST /api/v1/youtube/metadatastill works as a deprecated alias of/video. Use/videofor new code.
/search with search. Use sort_by: view_count for the most-watched result. Read results[].video_id./video with video_id (accepts a full watch URL too) for description, length_seconds, view_count, keywords, and captions[]./comments, then /comments/replies with a comment's reply_cursor to expand a thread./transcript for a plain transcript (format: text) or timed subtitles (format: srt)./streams for direct format URLs./channel/resolve, then call /channel, /channel/videos, /channel/shorts, or /channel/community.Paginated endpoints return next_cursor and has_more; pass next_cursor back as cursor for the next page.
/search)| Parameter | Type | Default | Description |
|---|---|---|---|
search | string | required | Search query — note: this field is search, not query |
upload_date | string | -- | last_hour, today, this_week, this_month, this_year |
type | string | -- | video, channel, playlist, or movie |
duration | string | -- | short, medium, long |
sort_by | string | relevance | relevance, date, view_count, rating |
features | string[] | -- | Any of hd, 4k, subtitles, creative_commons, live, 360, 3d, hdr, vr180 |
cursor | string | -- | Pagination cursor from a prior next_cursor |
Legacy boolean flags (subtitles, creative_commons, hd, 4k, live, 360, 3d, hdr, vr180) are still accepted for backward compatibility; prefer the features array.
/shorts)search* , sort_by, cursor.
/suggestions)search* , language (default en), region (default US).
/video) and metadata aliasvideo_id* — accepts a raw ID or a full watch URL.
/comments)video_id* , cursor.
/comments/replies)video_id* , reply_cursor* (a comment's reply_cursor), cursor.
/transcript)video_id* , language (default en), format (text for plain, srt for timed; default text).
/related)video_id* , cursor.
/streams)video_id* .
/channel/search)search* , cursor.
/channel)channel_id* — accepts a channel ID, @handle, or channel URL.
channel_id* , cursor.
/channel/resolve)channel* — a @handle or channel URL. Returns channel_id and channel_url.
import requests
BASE = "https://api.scavio.dev"
# Your key from https://scavio.dev. Load it from your environment or secret
# store in real code - keep it out of source control.
API_KEY = "sk_your_key_here"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 1. Search — use "search" field, not "query"
search = requests.post(f"{BASE}/api/v1/youtube/search", headers=HEADERS,
json={"search": "langchain tutorial", "type": "video", "sort_by": "view_count"}).json()
video_id = search["data"]["results"][0]["video_id"]
# 2. Full video metadata (captions list included)
video = requests.post(f"{BASE}/api/v1/youtube/video", headers=HEADERS,
json={"video_id": video_id}).json()
# 3. Transcript as plain text
transcript = requests.post(f"{BASE}/api/v1/youtube/transcript", headers=HEADERS,
json={"video_id": video_id, "language": "en", "format": "text"}).json()
# 4. Resolve a handle, then pull the channel's videos
resolved = requests.post(f"{BASE}/api/v1/youtube/channel/resolve", headers=HEADERS,
json={"channel": "@freecodecamp"}).json()
channel_id = resolved["data"]["channel_id"]
videos = requests.post(f"{BASE}/api/v1/youtube/channel/videos", headers=HEADERS,
json={"channel_id": channel_id}).json()
Every response uses the envelope { data, response_time, credits_used, credits_remaining }. Key data fields per endpoint:
results[] (type, video_id, title, url, description_snippet, thumbnail, duration_text, view_count, published_time, channel{id,name,url}), plus shorts, channels, playlists, next_cursor, has_more.results[] (video_id, title, url, thumbnail, view_count, published_time, author, channel_id), next_cursor, has_more.suggestions[] (strings), total_count.video_id, title, author, channel_id, channel_url, published_at, description, length_seconds, view_count, keywords[], thumbnail, playability_status, chapters, captions[] (language_code, language_name, url).comments[] (comment_id, text, like_count, reply_count, published_time, reply_cursor, author{channel_id,name,url,avatar,is_verified,is_creator}), next_cursor, has_more.replies[] (same item shape as a comment), next_cursor, has_more.video_id, language_code, language_name, format, content.results[] (video_id, title, url, author, channel_id, channel_url, thumbnail, view_count, published_time, length_seconds), total_count.results[] (channel_id, name, handle, url, thumbnail, subscriber_count, description, verified), next_cursor, has_more, total_count.channel_id, title, description, handle, url, subscriber_count, video_count, view_count, country, creation_date, verified, has_business_email, avatar, banner, links[].channel_id, results[] (video_id, title, url, thumbnail, duration_text, view_count, published_time, is_live), next_cursor, has_more.channel_id, results[] (video_id, title, url, thumbnail, view_count), next_cursor, has_more, total_count.channel_id, posts[] (post_id, url, text, author_name, author_channel_id, published_time, vote_count, comment_count, images[], attachment_type), next_cursor, has_more.channel_id, channel_url.video_id, title, author, length_seconds, view_count, is_live, formats[], adaptive_formats[], available_qualities[], expires_in_seconds.{
"data": {
"results": [
{
"type": "video",
"video_id": "sVcwVQRHIc8",
"title": "Learn RAG From Scratch - Python AI Tutorial",
"url": "https://www.youtube.com/watch?v=sVcwVQRHIc8",
"duration_text": "2:33:11",
"view_count": 1258310,
"published_time": "1 year ago",
"thumbnail": "https://i.ytimg.com/vi/sVcwVQRHIc8/hq720.jpg",
"channel": { "id": "UC8butISFwT-Wl7EV0hUK0BQ", "name": "freeCodeCamp.org", "url": "https://www.youtube.com/@freecodecamp" }
}
],
"next_cursor": "EpMD...",
"has_more": true
},
"credits_used": 2,
"credits_remaining": 998
}
search, not query — this is different from other Scavio endpoints.search and shorts cost 2, streams costs 3, transcript costs 8, and every other endpoint costs 1. Inform the user before paginating through many pages, especially transcripts./metadata is a deprecated alias of /video; use /video in new code./streams expire (expires_in_seconds) — use them promptly.400 means an invalid parameter (e.g. a missing video_id or channel_id) — fix and retry.401 means the API key is invalid or missing. Check SCAVIO_API_KEY.429 means rate or usage limit exceeded. Wait before retrying. See rate limits.502 / 503 mean upstream is temporarily unavailable. Wait a few seconds before retrying.language, retry with language: en or check /video captions[] for available languages.SCAVIO_API_KEY is not set, prompt the user to export it before continuing.pip install langchain-scavio==4.0.2
from langchain_scavio import ScavioSearchTool
tool = ScavioSearchTool(engine="youtube")