Scraping a YouTube channel, for an app, means two reads: who the channel is, and what it uploaded. Both are GET requests. Neither one is the official YouTube Data API. Both return the public fields SocialScrape records for those routes, and both are in beta.
Send the key as x-api-key. See authentication.
The channel#
GET /v1/youtube/channel returns the name, avatar, subscribers, video and view counts, join date, country and linked links. Pass a handle, an id (the UC... channel id) or a channel url. One of the three is required. username aliases handle. channelId and channel_id alias id. A URL can be /@handle, /channel/UC... or /c/name.
The recorded request uses a handle.
curl -G "https://api.socialscrape.io/v1/youtube/channel" \
-H "x-api-key: $SOCIALSCRAPE_API_KEY" \
--data-urlencode "handle=NASA"import os
import requests
params = {
"handle": "NASA",
}
res = requests.get(
"https://api.socialscrape.io/v1/youtube/channel",
headers={"x-api-key": os.environ["SOCIALSCRAPE_API_KEY"]},
params=params,
)
body = res.json()
if body["ok"]:
print(body["data"])
else:
print(body["error"]["code"], body["error"]["message"])const url = new URL("https://api.socialscrape.io/v1/youtube/channel");
url.search = new URLSearchParams({
"handle": "NASA"
}).toString();
const res = await fetch(url, {
headers: { "x-api-key": process.env.SOCIALSCRAPE_API_KEY! },
});
const body = await res.json();
if (body.ok) {
console.log(body.data);
} else {
console.error(body.error.code, body.error.message);
}data is a profile. platform is youtube. You get id, handle, name, headline, url, bio, avatar_url, banner_url, verified, is_private, external_url, links, location, category and created_at. Empty platform fields are null.
stats.followers is the subscriber count as returned. stats.posts is the video count. stats.views is the channel view total. stats.following and stats.likes are null when the channel page does not have them.
extra carries the parts that do not fit the shared profile. On a channel that includes channel_url, rss_url, keywords, joined_text, is_family_safe, is_live, is_unlisted, verified_kind, video_count_text, subscribers_text and subscribers_approximate. Read subscribers_approximate before you print stats.followers as an exact integer. When it is true, YouTube rounded the figure, and subscribers_text is the label YouTube showed. facebook_profile_id is set when the channel page links a Facebook profile id. It is not a Facebook scrape by itself.
Sample. The recorded handle is NASA, and the sample is shortened. Cite it as a sample, not as today's subscriber total.
Errors on this route are invalid_params, unsupported_url and not_found. A bad URL shape is unsupported_url. An unknown channel is not_found. Do not retry either.
The uploads#
GET /v1/youtube/channel/videos lists the channel's uploads, newest first or most popular. You page with cursor (YouTube's continuation token). The same one-of applies: handle, id or url.
sort is latest or popular. Changing sort restarts the cursor chain. include_extras also fetches likes, comment count and description per video. The reference says that is slower and can produce more errors, and that the single video endpoint returns everything. Leave it off unless you need those columns on every row.
The recorded request asks for popular uploads on a handle.
curl -G "https://api.socialscrape.io/v1/youtube/channel/videos" \
-H "x-api-key: $SOCIALSCRAPE_API_KEY" \
--data-urlencode "handle=MrBeast" \
--data-urlencode "sort=popular"import os
import requests
params = {
"handle": "MrBeast",
"sort": "popular",
}
res = requests.get(
"https://api.socialscrape.io/v1/youtube/channel/videos",
headers={"x-api-key": os.environ["SOCIALSCRAPE_API_KEY"]},
params=params,
)
body = res.json()
if body["ok"]:
print(body["data"])
else:
print(body["error"]["code"], body["error"]["message"])const url = new URL("https://api.socialscrape.io/v1/youtube/channel/videos");
url.search = new URLSearchParams({
"handle": "MrBeast",
"sort": "popular"
}).toString();
const res = await fetch(url, {
headers: { "x-api-key": process.env.SOCIALSCRAPE_API_KEY! },
});
const body = await res.json();
if (body.ok) {
console.log(body.data);
} else {
console.error(body.error.code, body.error.message);
}data.object is list. Each data.items entry is a post: id, url, type, title, text, published_at, duration_seconds, author, stats, media. stats.views is on the row. Likes and comment counts stay null unless include_extras was set or you call GET /v1/youtube/video for that id. extra.published_at_approximate marks a date that is not exact.
cursor and has_more are on the envelope and inside data. When has_more is true, send the same parameters plus cursor set to the value you got. Stop when has_more is false. Each page is its own credit. The loop is documented in pagination.
parent on the list points at the channel.
Cost and cache#
A channel is 1 credit. Each page of videos is 1 credit. A page of fifty videos is not one credit if it took several cursors. Count the requests that returned ok: true and were not cached.
Both endpoints are cacheable for 30 days. Send max_age_days to accept a cached copy for 0 credits. Failed requests cost 0. The balance rules, the 100 credit signup grant and the pack prices are in credits and on pricing.
Limits#
You get the public channel and its upload list, paged. You do not get a private video, a member-only post, or comments, unless you call the comment endpoint on a video URL. Sponsor labels are a separate route, GET /v1/youtube/video/sponsors, and the use-case notes on this site call that detection experimental. Do not treat a missing sponsor row as proof of no sponsor.
sort=latest and sort=popular are the two values this list accepts. This is not YouTube search. Search has its own sort rules: latest and rating are refused there. Do not copy search parameters onto the channel list.
Rate limits are per team. Free credits allow 30 requests a minute. A 429 is free and retryable. See rate limits.
The API is in early access. These routes are beta, so new fields can appear. Null stays null when YouTube did not send a value.
Next#
Channel facts and the sample are on the YouTube channel API page and in the reference. Uploads are the channel videos API and how to scrape YouTube channel videos. The channel tutorial is how to scrape a YouTube channel, with Python and JavaScript. The group hub is the YouTube API.
Watching a channel for new uploads, instead of polling, is a monitor on the list endpoint. See monitors and webhooks and the monitors reference.