# YouTube Scraper API > Source: https://scrape.do/documentation/youtube-api/ Scrape YouTube search results, channels, playlists, and Shorts shelves as structured JSON ![YouTube API](/uploads/youtube-api.png) The YouTube API is a specialized plugin that searches YouTube and returns structured JSON for the search result page: videos, channels, playlists, Shorts shelves, ads, and the "people also watched" / "related searches" rails. One HTTP call. No JavaScript rendering. No render fee. > [!NOTE] > **Credit Usage:** Each successful request costs **10 credits**. Pagination uses the `sp` continuation token that comes back in `pagination.next_page_token`. ## Key Features - **Structured JSON Output**: Up to 20 video results per page plus channels, playlists, Shorts shelves, ads, and discovery rails (`people_also_watched`, `from_related_searches`, `channels_new_to_you`, `explore_more`). - **Result Type Filters**: `sp` tokens for videos-only, channels-only, or playlists-only — switches the populated array. - **Sort Modes**: relevance (default), rating, upload date, view count. - **Duration Filters**: under 4 minutes, 4–20 minutes, over 20 minutes. - **Feature Filters**: 4K, HD, LIVE, closed captions. - **Upload Date Filters**: last hour, today, this week, this month, this year. - **Localization**: `hl` controls UI language (published-date, duration, view-count strings); `gl` influences ranking and shelf eligibility. - **Device Emulation**: Desktop or mobile layout via `device`. - **Pagination**: Single `sp` parameter doubles as filter token *and* continuation cursor — the plugin routes them automatically. - **No Blocks or CAPTCHAs**: Anti-bot is handled by Scrape.do. --- ## Endpoint ``` GET https://api.scrape.do/plugin/google/youtube ``` --- ## Request Parameters ### Required | Parameter | Type | Description | |-----------|------|-------------| | `token` | string | Your Scrape.do API authentication token | | `search_query` | string | Search terms (e.g., `best laptop 2025`, `macbook pro m3`). Alias: `q` | ### Localization | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `hl` | string | `en` | Interface language (`en`, `de`, `fr`, `ja`, `tr`, `es`, …). Controls `published_date`, `length`, and `views` text. | | `gl` | string | `us` | Country code (`us`, `gb`, `de`, `fr`, `jp`, …). Influences ranking and which shelves appear. | For the cleanest locale experience, match `hl` to `gl` (e.g., `hl=de&gl=de`). ### Device | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `device` | string | `desktop` | `desktop` or `mobile`. Mobile returns the mobile layout. | ### Filters, Sort & Pagination | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `sp` | string | — | YouTube's opaque token. Short values control sort / result type / duration / features / upload date. Long values are continuation cursors emitted in `pagination.next_page_token`. The plugin routes both automatically. See [Common `sp` Values](#common-sp-values). | --- ## Example Usage ### Basic search **cURL (API mode)** ```bash curl --location --request GET 'https://api.scrape.do/plugin/google/youtube?token=&search_query=best+laptop+2025' ``` **Python (API mode)** ```python import requests import json token = "" url = f"https://api.scrape.do/plugin/google/youtube?token={token}&search_query=best+laptop+2025" response = requests.request("GET", url) print(json.dumps(response.json(), indent=2)) ``` **Node.js (API mode)** ```javascript const axios = require('axios'); const token = ""; const url = `https://api.scrape.do/plugin/google/youtube?token=${token}&search_query=best+laptop+2025`; axios.get(url) .then(response => { console.log(JSON.stringify(response.data, null, 2)); }) .catch(error => { console.error(error); }); ``` *(Go, Ruby, Java, C#, PHP examples are also available on the HTML version.)* ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=best+laptop+2025&token=YOUR_TOKEN" ``` ### German locale ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=beste+laptop+2025&hl=de&gl=de&token=YOUR_TOKEN" ``` `published_date`, `length`, and view-count strings render in German. ### Sort by view count ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=best+laptop+2025&sp=CAM%3D&token=YOUR_TOKEN" ``` ### Channels only ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=tech+reviewer&sp=EgIQAg%3D%3D&token=YOUR_TOKEN" ``` Populates `channel_results[]` instead of videos. ### Playlists only ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=learn+golang&sp=EgIQAw%3D%3D&token=YOUR_TOKEN" ``` Populates `playlist_results[]`. ### Long-form videos (over 20 minutes) ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=podcast+interview&sp=EgIYAg%3D%3D&token=YOUR_TOKEN" ``` ### 4K videos only ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=nature+documentary&sp=EgJwAQ%3D%3D&token=YOUR_TOKEN" ``` ### Live now ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=formula+1&sp=EgJAAQ%3D%3D&token=YOUR_TOKEN" ``` ### Mobile layout ```bash curl "https://api.scrape.do/plugin/google/youtube?search_query=workout+videos&device=mobile&token=YOUR_TOKEN" ``` ### Pagination ```bash # Page 1 curl "https://api.scrape.do/plugin/google/youtube?search_query=best+laptop+2025&token=YOUR_TOKEN" # → response includes pagination.next_page_token = "EqwDEhBiZXN0..." # Page 2: pass that token as sp curl "https://api.scrape.do/plugin/google/youtube?search_query=best+laptop+2025&sp=EqwDEhBiZXN0...&token=YOUR_TOKEN" ``` The same `sp` parameter handles both filters and continuation tokens. Short values filter; long values paginate. --- ## Response ### Top-Level Structure ```json { "search_parameters": { ... }, "search_information": { ... }, "ads_results": [ ... ], "video_results": [ ... ], "channel_results": [ ... ], "playlist_results": [ ... ], "shorts_results": [ ... ], "people_also_watched": [ ... ], "people_also_search_for": [ ... ], "channels_new_to_you": [ ... ], "from_related_searches": [ ... ], "explore_more": [ ... ], "related_searches": [ ... ], "pagination": { ... } } ``` Collections that have no items for a given query are omitted. The one exception is `video_results`, which is always present — returns `[]` when empty. ### `search_parameters` Echo of the request. ```json { "engine": "google_youtube", "search_query": "best laptop 2025", "gl": "us", "hl": "en" } ``` `sp` appears only when set. ### `search_information` ```json { "total_results": 16406969 } ``` | Field | Type | Description | |---|---|---| | `total_results` | integer | YouTube's estimated total. May be `0` on some continuation pages. | | `video_results_state` | string | Status label (e.g., when YouTube auto-corrects spelling). Present only when set. | ### `video_results[]` Always present. Returns `[]` when no videos are found. ```json { "position_on_page": 2, "title": "The Best Laptops of 2025", "link": "https://www.youtube.com/watch?v=PKshhTHyoZU", "video_id": "PKshhTHyoZU", "channel": { "name": "Just Josh", "link": "https://www.youtube.com/@JustJoshTech", "verified": true, "thumbnail": "https://yt3.ggpht.com/..." }, "published_date": "4 months ago", "views": 313829, "length": "12:38", "description": "Save BIG on Your Laptop: ...", "extensions": ["4K"], "thumbnail": { "static": "https://i.ytimg.com/vi/PKshhTHyoZU/hqdefault.jpg", "rich": "https://i.ytimg.com/an/PKshhTHyoZU/..." }, "live": false } ``` | Field | Type | Always | Description | |---|---|:-:|---| | `position_on_page` | integer | yes | 1-based position | | `title` | string | yes | Video title | | `link` | string | yes | Canonical watch URL | | `video_id` | string | yes | YouTube video id | | `channel.name` | string | | Channel display name | | `channel.link` | string | | Channel URL | | `channel.verified` | bool | | `true` when the channel has a verified badge | | `channel.thumbnail` | string | | Channel avatar URL | | `published_date` | string | | Human-readable age, localized to `hl` (`"4 months ago"`, `"vor 4 Monaten"`) | | `views` | integer | | View count parsed to integer (`47,427` → `47427`, `1.2M` → `1200000`) | | `length` | string | | Duration (`"12:38"`, `"1:05:22"`) | | `description` | string | | Snippet text shown under the result | | `extensions` | string[] | | Badges (`"4K"`, `"LIVE"`, `"New"`, `"CC"`) | | `thumbnail.static` | string | | Static thumbnail URL | | `thumbnail.rich` | string | | Animated preview URL when YouTube provides one | | `live` | bool | | `true` when the video is a live stream | ### `channel_results[]` Populated when the query surfaces channel cards — most often with `sp=EgIQAg==` (Channels filter). ```json { "position_on_page": 2, "title": "Just Josh", "link": "https://www.youtube.com/@JustJoshTech", "verified": true, "handle": "@JustJoshTech", "subscribers": 379000, "description": "Finding You The Best Laptop!", "thumbnail": "https://yt3.ggpht.com/..." } ``` | Field | Type | Description | |---|---|---| | `position_on_page` | integer | 1-based position | | `title` | string | Channel display name | | `link` | string | Channel URL | | `verified` | bool | Verified badge | | `handle` | string | `@handle` slug | | `subscribers` | integer | Subscriber count parsed to integer | | `description` | string | Channel description snippet | | `thumbnail` | string | Channel avatar URL | ### `playlist_results[]` Populated when the query surfaces playlist cards — most often with `sp=EgIQAw==` (Playlists filter). ```json { "position_on_page": 2, "title": "Best Gaming Laptops 2025", "link": "https://www.youtube.com/playlist?list=PLFBbwFM8jIbOfpMghQOpdS8E8tJMweb3h", "channel": { "name": "Jarrod'sTech", "link": "https://www.youtube.com/@JarrodsTech" }, "videos": [ { "link": "https://www.youtube.com/watch?v=zqjHX_WSyz8&list=PLFBbwFM8jIbOfpMghQOpdS8E8tJMweb3h" } ], "video_count": 23, "thumbnail": "https://i.ytimg.com/vi/zqjHX_WSyz8/hq720.jpg" } ``` | Field | Type | Description | |---|---|---| | `position_on_page` | integer | 1-based position | | `title` | string | Playlist title | | `link` | string | Playlist URL | | `channel.name` | string | Uploader display name | | `channel.link` | string | Uploader channel URL | | `videos` | object[] | Preview videos. Each entry carries `title`, `length`, `link` when available | | `video_count` | integer | Total video count on the playlist badge | | `thumbnail` | string | Playlist cover thumbnail | ### `shorts_results[]` Array of Shorts shelves. Each shelf is a block that renders inline among regular video results. ```json { "position_on_page": 5, "shorts": [ { "title": "Top 3 Laptops", "link": "https://www.youtube.com/shorts/abc123", "thumbnail": "https://i.ytimg.com/vi/abc123/oardefault.jpg", "views_original": "2.1M", "views": 2100000, "video_id": "abc123" } ] } ``` ### `ads_results[]` Promoted entries that appeared on the page. ```json { "position_on_page": 1, "title": "Microsoft® Surface", "link": "https://www.googleadservices.com/pagead/aclk?...", "website": "https://www.googleadservices.com/pagead/aclk?...", "channel": { "name": "Microsoft", "thumbnail": "https://lh3.googleusercontent.com/..." }, "description": "Discover the new Surface lineup.", "thumbnail": { "static": "https://lh3.googleusercontent.com/..." } } ``` ### Discovery Rails Each rail is an array of the same shape as `video_results[]`. Present only when YouTube renders the corresponding shelf. | Field | Renders when | |---|---| | `people_also_watched` | "People also watched" shelf | | `people_also_search_for` | "People also search for" shelf (video items) | | `channels_new_to_you` | "Channels new to you" shelf | | `from_related_searches` | "From related searches" shelf | | `explore_more` | "Explore more" / "Latest from" shelf | ### `related_searches` Keyword refinement chips rendered above results. ```json [ { "query": "best laptop 2025 under 1000" }, { "query": "best gaming laptop 2025" } ] ``` ### `pagination` Present on every response that YouTube advertises a continuation for. ```json { "current": "https://www.youtube.com/results?gl=us&hl=en&search_query=best+laptop+2025", "next": "https://www.youtube.com/results?gl=us&hl=en&search_query=best+laptop+2025&sp=EqwDEhBiZXN0...", "next_page_token": "EqwDEhBiZXN0..." } ``` | Field | Type | Description | |---|---|---| | `current` | string | The URL the plugin fetched for this page | | `next` | string | Ready-to-inspect URL for the next page | | `next_page_token` | string | Raw continuation token. Pass this back as `sp` on a new request | --- ## Common `sp` Values `sp` is YouTube's opaque filter / sort / pagination token. Short values control filters and sort; long values are continuation cursors emitted in `pagination.next_page_token`. The plugin accepts both. ### Sort Order | `sp` | Effect | |---|---| | *(omit)* | Relevance (default) | | `CAE%3D` | Sort by rating | | `CAI%3D` | Sort by upload date (newest first) | | `CAM%3D` | Sort by view count | ### Result Type | `sp` | Effect | |---|---| | `EgIQAQ%3D%3D` | Videos only | | `EgIQAg%3D%3D` | Channels only → populates `channel_results` | | `EgIQAw%3D%3D` | Playlists only → populates `playlist_results` | ### Duration | `sp` | Effect | |---|---| | `EgIYAQ%3D%3D` | Under 4 minutes | | `EgIYAw%3D%3D` | 4–20 minutes | | `EgIYAg%3D%3D` | Over 20 minutes | ### Features | `sp` | Effect | |---|---| | `EgJwAQ%3D%3D` | 4K | | `EgIgAQ%3D%3D` | HD | | `EgJAAQ%3D%3D` | Live now | | `EgQQARgB` | Subtitles / closed captions | ### Upload Date | `sp` | Effect | |---|---| | `EgIIAQ%3D%3D` | Last hour | | `EgIIAg%3D%3D` | Today | | `EgIIAw%3D%3D` | This week | | `EgIIBA%3D%3D` | This month | | `EgIIBQ%3D%3D` | This year | > [!NOTE] > These tokens are defined by YouTube and can change without notice. When a token is no longer accepted, YouTube returns an unfiltered result set. --- ## Notes - **Organic variance.** YouTube reorders search results continuously. Consecutive calls with identical parameters can return 60–95% overlap depending on the query. This is inherent to the surface, not the plugin. - **Shorts availability.** Shorts shelves appear unpredictably. Expect 0, 1, or multiple `shorts_results` entries depending on the query and locale. Absence doesn't mean failure. - **Ads are best-effort.** YouTube runs many layouts in parallel; unknown layouts are skipped rather than returned as partial objects. - **Locale fidelity.** `hl` controls metadata strings (`published_date`, `length`, view-count suffixes, shelf titles). `gl` influences ranking and which shelves render. - **Pagination depth.** Continuation pagination is stable for tens of pages. Very deep pagination (>50 pages) may start returning empty `video_results` as YouTube exhausts the feed. --- ## Error Handling ```json { "error": "error_code" } ``` | Status | Error | Cause | |---|---|---| | `400` | `token is required` | `token` query parameter missing | | `400` | `search_query is required` | Neither `search_query` nor `q` provided | | `400` | `device must be one of: desktop, mobile` | Invalid `device` value | | `400` | `failed to construct YouTube URL` | Internal URL construction failed (rare — malformed inputs) | | `401` | `The API Token is inactive or incorrect.` | Invalid API token | | `500` | `decompression failed` | Response body decompression failed | | `500` | `internal server error` | Unhandled exception. Report if persistent | | `502` | `upstream returned truncated page` | YouTube returned a partial response. Retry | | `502` | `failed to parse search results` | YouTube returned an unexpected payload shape. Retry; report if persistent | | `502` | `unexpected response` | Upstream returned non-200. Retry | | `502` | `request failed` | Network-level failure. Retry | ---