YouTube Shorts Trend Research API: A Python Workflow

Research YouTube Shorts trends with keyword search, continuation pagination, video details, channel context, comments, and honest local scoring.

A dark research timeline organizing YouTube Shorts signals into trends and questions

YouTube Shorts trend research often starts with a misleading shortcut: sort a search by views and call the winners “trends.” That ignores publication time, ambiguous formatted counts, channel baselines, and the questions viewers actually ask. This tutorial builds a defensible workflow from the public endpoints in the YouTube API catalog: search, page, normalize, enrich a shortlist, and preserve the evidence behind every conclusion.

The live calls were made on October 25, 2026 (UTC) with “AI agents.” The nested fields are observed response data. Endpoint schemas and availability can change. For channel-first research, see the YouTube channel research API guide.

Key takeaway

  • Search results can carry formatted view counts such as 5.8K views; parse them before sorting.
  • The tested continuation request needed both the original keyword and continuation_token.
  • One tested combination, this_month plus view_count, returned no Shorts; an empty page is data, not a reason to invent results.
  • Enrich only a shortlist with video info, comments, and channel Shorts.

What the endpoint actually returned

The unfiltered search returned a shorts array, the original keyword, and a continuation token. The first item exposed video_id, title, URL, thumbnail, and a formatted view-count string. Author and channel fields were present but empty on that item, so the pipeline cannot assume search always identifies a channel.

Evidence card showing the first YouTube Shorts search result The search response is useful for discovery, but its formatted counts need normalization.

The first attempt to request page two with only the token returned HTTP 400. Sending the keyword with the same token succeeded and produced another Shorts page plus a new continuation token. This observed requirement belongs in saved job state and regression tests.

Evidence card showing the successful YouTube Shorts pagination rule For this endpoint and test, page two required the original keyword as well as the token.

The comment endpoint returned a comment list and its own continuation token. It is most useful after ranking: repeated questions can reveal follow-up demand that raw views cannot show.

Evidence card showing YouTube comment results and continuation token Comments add qualitative demand signals after deterministic filtering.

Install and authenticate

python -m pip install requests
export SANDBASE_API_KEY="your_key_here"
import os, time, requests

BASE = "https://api.sandbase.ai/v1/api"
HEADERS = {"Authorization": f"Bearer {os.environ['SANDBASE_API_KEY']}",
           "Content-Type": "application/json"}

def call(model, payload, retries=2):
    for attempt in range(retries + 1):
        r = requests.post(f"{BASE}/{model}", headers=HEADERS,
                          json=payload, timeout=90)
        if r.status_code < 500 and r.status_code != 429:
            r.raise_for_status(); break
        if attempt == retries: r.raise_for_status()
        time.sleep(2 ** attempt)
    body = r.json()
    if body.get("status") != "completed":
        raise RuntimeError(body.get("error") or body.get("status"))
    try: return body["outputs"][0]["data"]
    except (KeyError, IndexError, TypeError) as exc:
        raise RuntimeError("Missing outputs[0].data") from exc

Search and page without losing context

def search_shorts(keyword, pages=2, sort_by=None, upload_date=None):
    token, rows, seen = None, [], set()
    for _ in range(pages):
        payload = {"keyword": keyword}
        if sort_by: payload["sort_by"] = sort_by
        if upload_date: payload["upload_date"] = upload_date
        if token: payload["continuation_token"] = token
        page = call("youtube/web-v2/shorts-search-v2", payload)
        for item in page.get("shorts") or []:
            video_id = item.get("video_id")
            if not video_id or video_id in seen: continue
            seen.add(video_id)
            rows.append(item)
        token = page.get("continuation_token")
        if not token: break
    return rows

Do not automatically loosen filters when a page is empty. Record the empty result, then run a separately labelled broader query. In my test, the restrictive query returned an empty shorts array while still returning a continuation token. That is a useful edge case for monitoring.

Normalize formatted counts

import re

def parse_count(value):
    if isinstance(value, int): return value
    if not value: return None
    text = str(value).upper().replace(",", "")
    match = re.search(r"([0-9]+(?:\.[0-9]+)?)\s*([KMB]?)", text)
    if not match: return None
    number = float(match.group(1))
    scale = {"": 1, "K": 1_000, "M": 1_000_000, "B": 1_000_000_000}
    return int(number * scale[match.group(2)])

for row in results:
    row["views_numeric"] = parse_count(row.get("view_count"))

Keep the original string too. If YouTube changes localization or formatting, the raw value makes the parser’s decision auditable.

Enrich the shortlist

def enrich(video_id, channel_id=None):
    info = call("youtube/web-v2/video-info-v2", {"video_id": video_id})
    comments = call("youtube/web-v2/video-comments", {
        "video_id": video_id, "sort_by": "top",
        "need_format": True, "language_code": "en",
    })
    channel = None
    if channel_id:
        channel = call("youtube/web-v2/channel-shorts", {
            "channel_id": channel_id, "need_format": True
        })
    return {"info": info, "comments": comments.get("comments") or [],
            "channel_shorts": channel}

Channel enrichment is conditional because the first observed search item had an empty channel ID, and the tested video-info response exposed only publish_date, rating, thumbnail_url, and video_id. A robust pipeline skips unavailable enrichment instead of constructing a channel identifier.

A separate check used OpenAI’s public channel ID and confirmed that channel-shorts completed; it does not connect the search result above to OpenAI. When a channel baseline is available, compare the Short with the median of a fixed recent sample. Add freshness only when publish_date parses successfully. Keep comment themes separate from quantitative scores: an LLM may cluster comments, but it should receive a bounded sample and return citations to source comment positions.

Configuration reference

EndpointRequiredUseful optional fieldsPagination
shorts-search-v2keyword on first requestsort_by, upload_date, continuation_tokenreturned continuation token
channel-shortschannel_id or channel_urlneed_format, tokenreturned continuation token
video-info-v2video_id or video_urlneed_formatnone
video-commentsvideo_idsort_by, language/country, need_format, tokenreturned continuation token

Production safeguards

Persist query, filters, token, capture time, and parser version together. Cap pages and comment samples. Retry 429/5xx and transient network failures with backoff; send 400 responses to review because changing the query silently changes the research question. Treat empty strings as unavailable, not valid IDs. Never log the API key or temporary media URLs.

The report should distinguish “top results for this query at this time” from platform-wide trends. Search is query-dependent and personalized systems can change. Use several related queries, compare recurring themes, and keep the sampled video IDs available to the reviewer.

Troubleshooting and FAQ

  • Page two returns 400: include the original keyword with the continuation token.
  • A filtered search is empty: preserve the result and run a separately named broader query.
  • View count sorts incorrectly: parse suffixes before sorting and keep the original string.
  • Channel ID is blank: skip channel enrichment; do not derive it from a title.
  • Comments are missing: the video may have no returned comments; keep the sample size at zero.

Does this identify every YouTube-wide trend?

No. It ranks evidence returned for explicit queries. Platform-wide claims need broader sampling and a documented methodology.

Can I use comments as training data?

This workflow is for public research. Review rights, terms, retention, and privacy requirements before any reuse beyond aggregate analysis.

Where can I check current options?

Use the live YouTube API catalog for current schemas and availability.