STRUCTURED DATA API

YouTube Scraper API

A YouTube scraper you call over HTTP: send a video, channel or playlist URL to /data and get views, likes, channel stats, chapters and video lists back as JSON — plus the transcript when you ask for it. No YouTube Data API quota or OAuth app. Flat 15 credits per page.

2,000 free API credits · No credit card required

Scrape YouTube videos, channels and playlists

Send the page's normal URL to /data. The page type is detected from the URL, and the response tells you which one it was in request_parameters.type.

Video

type: "video"

Title, description, views, likes, comment count, duration, publish date, category, hashtags, chapters, channel stats, caption languages and up to 20 related videos. Shorts and live streams too.

youtube.com/watch?v=VIDEO_ID youtu.be/VIDEO_ID youtube.com/shorts/VIDEO_ID youtube.com/live/VIDEO_ID

Channel

type: "channel"

Title, handle, description, subscribers, video and view counts, join date, country, links, avatar and banner, plus the latest videos from the Videos tab (up to 30).

youtube.com/@handle youtube.com/channel/UC… youtube.com/c/name youtube.com/user/name

Playlist

type: "playlist"

Title, description, video and view counts, the owning channel, and the videos in order (up to 100) with position, duration and views.

youtube.com/playlist?list=PLAYLIST_ID
These URLs return a 400 that isn't charged, with a message listing what is supported: search results (/results?search_query=…), hashtag pages, and the home and trending feeds. More page types and sites are added over time, so don't validate URLs on your side — send the URL and handle the 400.

How to scrape YouTube with one API call

No selectors, proxies, or headless browser to run. The page-scraping options (js, proxy, headers…) don't apply; country picks the proxy country (default us).

curl -G "https://api.webscraping.ai/data" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "url=https://www.youtube.com/watch?v=dQw4w9WgXcQ"
# Response (excerpt):
# {
#   "request_parameters": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
#                          "provider": "youtube", "type": "video"},
#   "parse_status": "ok",
#   "data": {
#     "video_id": "dQw4w9WgXcQ",
#     "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
#     "views": 1819213866,
#     "likes": 19407119,
#     "comment_count": 2400000,
#     "length_seconds": 213,
#     "published_date": "2009-10-24",
#     "category": "Music",
#     "is_live": false,
#     "channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley",
#                 "handle": "@RickAstleyYT", "subscribers": 4540000, "verified": true, ...},
#     "available_transcript_languages": [{"name": "English", "lang": "en"},
#                                        {"name": "English (auto-generated)", "lang": "en"}, ...],
#     "related_videos": [{"position": 1, "video_id": "...", "title": "...",
#                         "published_time": "2 years ago", "views": 12000000}, ...],
#     ...
#   }
# }
# pip install webscraping_ai
# https://pypi.org/project/webscraping-ai/
from webscraping_ai import Client

client = Client(api_key="YOUR_API_KEY")
result = client.data("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
print(result["request_parameters"]["provider"], result["parse_status"])
print(result["data"])
# Response (excerpt):
# {
#   "request_parameters": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
#                          "provider": "youtube", "type": "video"},
#   "parse_status": "ok",
#   "data": {
#     "video_id": "dQw4w9WgXcQ",
#     "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
#     "views": 1819213866,
#     "likes": 19407119,
#     "comment_count": 2400000,
#     "length_seconds": 213,
#     "published_date": "2009-10-24",
#     "category": "Music",
#     "is_live": false,
#     "channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley",
#                 "handle": "@RickAstleyYT", "subscribers": 4540000, "verified": true, ...},
#     "available_transcript_languages": [{"name": "English", "lang": "en"},
#                                        {"name": "English (auto-generated)", "lang": "en"}, ...],
#     "related_videos": [{"position": 1, "video_id": "...", "title": "...",
#                         "published_time": "2 years ago", "views": 12000000}, ...],
#     ...
#   }
# }
// npm install webscraping-ai
// https://www.npmjs.com/package/webscraping-ai
import { WebScrapingAI } from 'webscraping-ai';

const client = new WebScrapingAI({ apiKey: 'YOUR_API_KEY' });
const result = await client.data({ url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' });
console.log(result.request_parameters.provider, result.parse_status);
console.log(result.data);
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
//                          "provider": "youtube", "type": "video"},
//   "parse_status": "ok",
//   "data": {
//     "video_id": "dQw4w9WgXcQ",
//     "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
//     "views": 1819213866,
//     "likes": 19407119,
//     "comment_count": 2400000,
//     "length_seconds": 213,
//     "published_date": "2009-10-24",
//     "category": "Music",
//     "is_live": false,
//     "channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley",
//                 "handle": "@RickAstleyYT", "subscribers": 4540000, "verified": true, ...},
//     "available_transcript_languages": [{"name": "English", "lang": "en"},
//                                        {"name": "English (auto-generated)", "lang": "en"}, ...],
//     "related_videos": [{"position": 1, "video_id": "...", "title": "...",
//                         "published_time": "2 years ago", "views": 12000000}, ...],
//     ...
//   }
// }
<?php
// composer require webscraping-ai/webscraping-ai-php
// https://packagist.org/packages/webscraping-ai/webscraping-ai-php
require 'vendor/autoload.php';

use WebScrapingAI\Client;

$client = new Client('YOUR_API_KEY');
$result = $client->data(url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ');
echo $result['request_parameters']['provider'], ' ', $result['parse_status'], "\n";
print_r($result['data']);
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
//                          "provider": "youtube", "type": "video"},
//   "parse_status": "ok",
//   "data": {
//     "video_id": "dQw4w9WgXcQ",
//     "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
//     "views": 1819213866,
//     "likes": 19407119,
//     "comment_count": 2400000,
//     "length_seconds": 213,
//     "published_date": "2009-10-24",
//     "category": "Music",
//     "is_live": false,
//     "channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley",
//                 "handle": "@RickAstleyYT", "subscribers": 4540000, "verified": true, ...},
//     "available_transcript_languages": [{"name": "English", "lang": "en"},
//                                        {"name": "English (auto-generated)", "lang": "en"}, ...],
//     "related_videos": [{"position": 1, "video_id": "...", "title": "...",
//                         "published_time": "2 years ago", "views": 12000000}, ...],
//     ...
//   }
// }
# gem install webscraping_ai
# https://rubygems.org/gems/webscraping_ai
require 'webscraping_ai'

client = WebScrapingAI::Client.new(api_key: 'YOUR_API_KEY')
result = client.data('https://www.youtube.com/watch?v=dQw4w9WgXcQ')
puts "#{result['request_parameters']['provider']} #{result['parse_status']}"
puts result['data'].inspect
# Response (excerpt):
# {
#   "request_parameters": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
#                          "provider": "youtube", "type": "video"},
#   "parse_status": "ok",
#   "data": {
#     "video_id": "dQw4w9WgXcQ",
#     "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
#     "views": 1819213866,
#     "likes": 19407119,
#     "comment_count": 2400000,
#     "length_seconds": 213,
#     "published_date": "2009-10-24",
#     "category": "Music",
#     "is_live": false,
#     "channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley",
#                 "handle": "@RickAstleyYT", "subscribers": 4540000, "verified": true, ...},
#     "available_transcript_languages": [{"name": "English", "lang": "en"},
#                                        {"name": "English (auto-generated)", "lang": "en"}, ...],
#     "related_videos": [{"position": 1, "video_id": "...", "title": "...",
#                         "published_time": "2 years ago", "views": 12000000}, ...],
#     ...
#   }
# }
// go get github.com/webscraping-ai/webscraping-ai-go/v4
// https://pkg.go.dev/github.com/webscraping-ai/webscraping-ai-go/v4
package main

import (
    "context"
    "fmt"

    webscrapingai "github.com/webscraping-ai/webscraping-ai-go/v4"
)

func main() {
    client, _ := webscrapingai.NewClient(&webscrapingai.Config{APIKey: "YOUR_API_KEY"})
    res, _ := client.Data(context.Background(), &webscrapingai.DataOptions{
        URL: "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    })
    fmt.Println(res.RequestParameters.Provider, res.ParseStatus)
    fmt.Println(string(res.Data)) // raw JSON; its shape depends on the provider and page type
}
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
//                          "provider": "youtube", "type": "video"},
//   "parse_status": "ok",
//   "data": {
//     "video_id": "dQw4w9WgXcQ",
//     "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
//     "views": 1819213866,
//     "likes": 19407119,
//     "comment_count": 2400000,
//     "length_seconds": 213,
//     "published_date": "2009-10-24",
//     "category": "Music",
//     "is_live": false,
//     "channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley",
//                 "handle": "@RickAstleyYT", "subscribers": 4540000, "verified": true, ...},
//     "available_transcript_languages": [{"name": "English", "lang": "en"},
//                                        {"name": "English (auto-generated)", "lang": "en"}, ...],
//     "related_videos": [{"position": 1, "video_id": "...", "title": "...",
//                         "published_time": "2 years ago", "views": 12000000}, ...],
//     ...
//   }
// }
// Maven: ai.webscraping:webscraping-ai:4.2.0
// https://central.sonatype.com/artifact/ai.webscraping/webscraping-ai
import ai.webscraping.Client;
import ai.webscraping.Config;
import ai.webscraping.option.DataOptions;
import ai.webscraping.result.DataResult;

Client client = new Client(Config.builder().apiKey("YOUR_API_KEY").build());
DataResult result = client.data(DataOptions.builder()
    .url("https://www.youtube.com/watch?v=dQw4w9WgXcQ")
    .build());
System.out.println(result.getRequestParameters().getProvider() + " " + result.getParseStatus());
System.out.println(result.getData());
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
//                          "provider": "youtube", "type": "video"},
//   "parse_status": "ok",
//   "data": {
//     "video_id": "dQw4w9WgXcQ",
//     "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
//     "views": 1819213866,
//     "likes": 19407119,
//     "comment_count": 2400000,
//     "length_seconds": 213,
//     "published_date": "2009-10-24",
//     "category": "Music",
//     "is_live": false,
//     "channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley",
//                 "handle": "@RickAstleyYT", "subscribers": 4540000, "verified": true, ...},
//     "available_transcript_languages": [{"name": "English", "lang": "en"},
//                                        {"name": "English (auto-generated)", "lang": "en"}, ...],
//     "related_videos": [{"position": 1, "video_id": "...", "title": "...",
//                         "published_time": "2 years ago", "views": 12000000}, ...],
//     ...
//   }
// }
// dotnet add package WebScrapingAI
// https://www.nuget.org/packages/WebScrapingAI
using WebScrapingAI;

var client = new WebScrapingAIClient(new WebScrapingAIClientOptions { ApiKey = "YOUR_API_KEY" });
var result = await client.DataAsync(new DataRequest {
    Url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
});
Console.WriteLine($"{result.RequestParameters.Provider} {result.ParseStatus}");
Console.WriteLine(result.Data);
// Response (excerpt):
// {
//   "request_parameters": {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
//                          "provider": "youtube", "type": "video"},
//   "parse_status": "ok",
//   "data": {
//     "video_id": "dQw4w9WgXcQ",
//     "title": "Rick Astley - Never Gonna Give You Up (Official Video) (4K Remaster)",
//     "views": 1819213866,
//     "likes": 19407119,
//     "comment_count": 2400000,
//     "length_seconds": 213,
//     "published_date": "2009-10-24",
//     "category": "Music",
//     "is_live": false,
//     "channel": {"id": "UCuAXFkgsw1L7xaCfnd5JJOw", "name": "Rick Astley",
//                 "handle": "@RickAstleyYT", "subscribers": 4540000, "verified": true, ...},
//     "available_transcript_languages": [{"name": "English", "lang": "en"},
//                                        {"name": "English (auto-generated)", "lang": "en"}, ...],
//     "related_videos": [{"position": 1, "video_id": "...", "title": "...",
//                         "published_time": "2 years ago", "views": 12000000}, ...],
//     ...
//   }
// }

Trimmed, and the counts are illustrative — they change constantly. Fields a page doesn't expose come back as null, though some flags come back false and lists come back empty. data can be null when parse_status is parse_failed or not_found, so check it before reading fields.

Transcripts in the same call

Add transcript=true on a video URL to get the captions in data.transcript: the full text plus timed segments (text, start, duration in seconds). transcript_language picks a caption language, e.g. de; without it, English is preferred, then the first available track. Uploaded captions beat auto-generated ones, and is_generated tells you which you got. Same 15 credits.

curl -G "https://api.webscraping.ai/data" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "url=https://www.youtube.com/watch?v=dQw4w9WgXcQ" \
  --data-urlencode "transcript=true" \
  --data-urlencode "transcript_language=en"

# Python SDK: client.data(url, transcript=True, transcript_language="en")
# CLI:        webscraping-ai data 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' --transcript

# "transcript": {
#   "language": "en",
#   "is_generated": false,
#   "text": "[♪♪♪] ♪ We're no strangers to love ♪ ♪ You know the rules and so do I ♪ ...",
#   "transcripts": [{"text": "[♪♪♪]", "start": 1.36, "duration": 1.68},
#                   {"text": "♪ We're no strangers to love ♪", "start": 18.64, "duration": 3.24}, ...]
# }

No captions in the requested language: transcript is null and the request is still charged. If the transcript fetch itself fails, the whole request fails with a 500 and isn't charged.

What the YouTube scraper returns

The key fields per page type. Names are snake_case across every site; the full contract is in the API reference.

type: "video"

FieldWhat it holds
video_id, title, link, descriptionThe basics. description is the full text; description_links lists its links.
views, likes, comment_countView and like counts. comment_count is YouTube's rounded display figure (e.g. 8.3K becomes 8300) and null when comments are off.
length_seconds, published_date, published_atDuration, the ISO publish date, and a full timestamp when YouTube provides one.
category, keywords, hashtagsThe video's category, its tag list and the hashtags from title and description.
is_live, is_upcoming, was_liveLive now, a scheduled stream or premiere, or a finished livestream.
is_unlisted, is_age_restricted, is_family_safeVisibility and audience flags.
channelid, name, handle, link, subscribers, thumbnail, verified.
chaptersChapter title, start_seconds and thumbnail.
available_transcript_languagesThe caption tracks you can request with transcript_language.
related_videosUp to 20 sidebar videos with position, title, views, length_seconds, published_time, channel.
transcriptWith transcript=true: language, is_generated, text and timed transcripts.

type: "channel"

FieldWhat it holds
channel_id, title, handle, descriptionIdentity and the About text.
subscribers, videos_count, view_countChannel totals.
joined_date, country, linksFrom the About panel: join date, country, and the external links as {title, url}.
keywords, avatar, banner, is_verifiedChannel keywords, images and the verification badge.
videosThe latest videos from the Videos tab (up to 30), each with video_id, title, views, length_seconds, published_time.

type: "playlist"

FieldWhat it holds
playlist_id, title, descriptionThe playlist itself.
video_count, view_countPlaylist totals.
channelThe owner: id, name, handle, link.
videosUp to 100 entries in playlist order, with position and the same video fields as a channel.

What's not included

Everything comes from what YouTube shows a logged-out visitor. That sets these limits.

No comment text. A video returns the comment count, not the comments themselves.
Relative dates on list items. Channel, playlist and related videos carry YouTube's published_time ("3 days ago"); only the video page has an exact published_date.
First page of lists only. Up to 30 channel videos and 100 playlist entries, no paging past that yet.
Videos tab only on channels. A channel URL (including its /shorts or /streams tab) returns the channel with the latest uploads from its Videos tab; Shorts and past streams aren't listed separately.
Need a page type or site that isn't supported? /ai/fields extracts the fields you describe in plain language from any public page, and /html returns the rendered HTML for your own parser.

Flat pricing: 15 credits per page

Every supported YouTube page type costs the same, with no extra charge for proxies or retries. That's about $1.74 per 1,000 pages on the $29 plan.

PlanPriceCreditsPages
Free $0 2,000 up to 133
Personal $29/mo 250,000 up to 16,666
Plus $99/mo 1,000,000 up to 66,666
Startup $249/mo 3,000,000 up to 200,000

The free plan's 2,000 credits renew monthly. All plans, including pay-as-you-go credits.

What's charged

Unsupported URL or page type: a 400, not charged.
Page couldn't be fetched: a 500, not charged.
Charged even without data: parse_status parse_failed (the page was fetched but couldn't be parsed) and not_found (the page doesn't exist) are successful requests and cost 15 credits, like ok.

Also from the terminal, AI agents, and n8n

CLI

webscraping-ai has a data command; pass - to read URLs from stdin, one per line.

webscraping-ai data 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'

MCP server

Claude, Cursor and other MCP clients get a webscraping_ai_data tool from the hosted MCP server (OAuth login, no API key to paste). Ask for a YouTube page's data in plain language and the agent calls it.

n8n

The WebScraping.AI n8n node has a Get Structured Data operation: feed it URLs from a sheet or a trigger and route the JSON onward, no code.

Frequently asked questions

Is it possible to scrape YouTube without the YouTube Data API?

Yes. Public video, channel and playlist pages carry their data in the page itself, and /data reads it from the URL you send: no Google Cloud project, API key or daily quota. You get JSON with the same field names every time.

Can I scrape YouTube comments?

Not the comment text. A video returns comment_count (YouTube's rounded display figure), plus the title, stats, chapters and transcript, but the comments themselves need a continuation call that /data doesn't make yet.

Is this the YouTube Data API?

No. The YouTube Data API is Google's own API, which needs an API project and has daily quota limits. This is a scraper API: it reads the public YouTube page for the URL you send and returns the result as JSON, with no Google quota. Some things the official API offers, like comment threads, aren't included.

Can I get a YouTube video's transcript?

Yes. Add transcript=true to a video request and data.transcript contains the full text plus timed segments. transcript_language picks the caption language; without it, English is preferred. Uploaded captions are preferred over auto-generated ones, and is_generated tells you which you got. It costs the same 15 credits.

Does it work for YouTube Shorts?

Yes. youtube.com/shorts/VIDEO_ID URLs are treated as videos and return the same fields as a regular watch page.

Is there a free YouTube scraper API?

Yes, for trying it out: the free plan includes 2,000 API credits every month, which covers 133 YouTube pages at 15 credits each. No credit card is needed. Paid plans start at $29/mo for 250,000 credits, or buy pay-as-you-go credits with no subscription from a $20 top-up (100,000 credits, about 6,666 pages).

How much does the YouTube Scraper API cost?

A flat 15 credits per page, for every supported YouTube page type. On the $29/mo plan (250,000 credits) that is up to 16,666 pages, or about $1.74 per 1,000. Unsupported URLs return a 400 and fetch failures a 500; neither is charged. parse_failed and not_found results are successful requests and are charged.

What happens if I send a URL you don't support?

You get a 400 that isn't charged, and its message lists what is supported. For pages /data doesn't cover, /ai/fields extracts the fields you describe from any public URL, and /html returns the rendered page for your own parser.

Other sites on the same endpoint

One API key, one request format, the same response envelope.

TikTok Scraper API Twitter (X) Scraper API LinkedIn Scraper API Instagram Scraper API Reddit Scraper API Google SERP API

Get YouTube data as JSON today

Get started with 2,000 free API credits. No credit card required.

Icon