List YouTube channel shorts
Returns a list of YouTube Shorts published by a channel, read from the channel's own Shorts shelf. Each short includes view count, like count, comment count, title, thumbnail, duration and exact publish date (measured 100% coverage on all six across 96 items, 2026-08-11), and unlike /v1/youtube/search?type=shorts every item carries channel identity. This is the Shorts complement to /v1/youtube/channel/videos, which is long-form only: the two sets are disjoint, so calling both and concatenating gives the channel's full catalogue for 2 credits. Every item carries post.ext.content_type (short here, video there) so the merged list stays separable. Send include=channel to add the channel's subscriber count, name, avatar and channel id to every row in the same call (1 credit). TITLES: the free per-video lookup swaps YouTube's English machine-translated listing title for the creator's own; a title not swapped carries post.ext.title_maybe_translated: true (exact_dates=false skips the lookup).
Request
- Base URL: https://www.socialcrawl.dev/v1
- URL: https://www.socialcrawl.dev/v1/youtube/channel/shorts
- Auth: API key in header x-api-key
Query parameters
Only shorts published on or after this date: YYYY-MM-DD (midnight UTC) or an ISO 8601 timestamp. Older shorts are left off the page, and the page that reaches one ends the walk: next_cursor is not returned and pagination.stopped_at is since. Pinned shorts sit out of date order and never end the walk. The page still costs what a page costs, so a daily poll pays for the pages it walks and no more.
The id (post.id) or URL (post.url) of the newest short you already hold. The page stops just before it: that short and everything after it are left off, next_cursor is not returned, and pagination.stopped_at is known_id. A pinned short never counts as the stop point. If it is not on this page the page is returned in full with its cursor, so keep walking. pagination.stopped_at is end when the list ran out first and null while there is more to walk.
YouTube channel handle without the @ symbol (one of: channelId, handle; at least one required)
Can pass channelId or handle (one of: channelId, handle; at least one required)
Sort by newest (descending publish date) or popular (descending view count). Both orderings are genuinely applied, unlike /v1/youtube/search's popular, which is a popularity-weighted ranking rather than a view sort.
Continuation token to get more videos. Get 'continuationToken' from previous response. Native upstream cursor param. Send the universal cursor instead: the API maps it to this name for you.
Set to channel (one token only) to add the channel's subscriber count to every row (post.ext.author_followers, YouTube's own figure, rounded to three significant figures above 1,000) plus post.author.display_name, .avatar_url and post.ext.channel_id where missing. Every row is the same channel, so this is one channel lookup for the whole page: 1 credit, refunded if the channel could not be read, and free when the channel was looked up recently. Adds well under a second (never more than 8). Read data.hydration for what it did.
On by default and free: every row is joined to the per-video lookup, one lookup per page (two on a page past 50 rows, side by side), adding about 0.2 to 0.7 seconds (never more than 3). The same lookup swaps the listing title, often YouTube's English machine translation, for the creator's own, and computed.language follows it; a title not swapped carries post.ext.title_maybe_translated: true. Set to false to skip the lookup and keep the listing title, marked by post.ext.title_maybe_translated. A row the lookup could not resolve keeps the listing title and the marker, and _warnings carries original_titles_partial (some rows) or original_titles_unavailable (none). The dates on this endpoint are exact either way.
Only rows published on or before this date: YYYY-MM-DD (that whole UTC day is included) or an ISO 8601 timestamp. Newer rows are left off each page and the walk does not stop, so older pages follow. A row with no date is kept. published_before, end_date and to_date are accepted and applied as until.
Universal pagination cursor. Send pagination.next_cursor from the previous response back verbatim: the API maps it to this endpoint's native continuationToken (cursor style). You never construct, decode, or look up a cursor. Omit it for page 1.
Headers
Send no-cache to bypass the response cache and force a live fetch. Billed at the normal endpoint cost; the fresh result is written back to cache for the next caller. Only the no-cache directive triggers this. See the Response Schema guide for details.
Optional UUID that makes the request safely retriable. The key is reserved atomically per account before billing. A concurrent retry receives 409 IDEMPOTENCY_IN_PROGRESS with a Retry-After of 1 second while the original is young, growing to a quarter of the time it has been running (at most 30); a crashed reservation expires after 5 minutes. A replay keeps the cached payload immutable except for billing metadata: credits_used becomes 0, idempotent_replay becomes true, and credits_remaining is refreshed to the current balance. A known current balance appears in both the body and X-Credits-Remaining header; no balance row resolves to 0. On a transient lookup failure, body credits_remaining is null and X-Credits-Remaining is omitted. Completed outcomes expire after 24 hours. If the claim store is unavailable, the request fails closed before billing. GET endpoints do not combine idempotent replay with Server-Sent Events: use Accept: application/json when sending this header. The unsupported key-plus-SSE combination is rejected before billing.
Response
Successful response
Example response
{
"success": true,
"platform": "youtube",
"endpoint": "/v1/youtube/channel/shorts",
"credits_used": 1,
"credits_remaining": 4999,
"request_id": "req-abc123",
"idempotent_replay": true,
"meta": {
"hint": {
"code": "search_multi",
"message": "You searched \"matcha\" on 3 platforms one call at a time; /v1/search/multi returns each platform's own search rows in one call at the same price per platform, and a platform with no rows is not charged.",
"method": "GET",
"path": "/v1/search/multi?query=matcha&platforms=instagram,tiktok,youtube"
}
},
"pagination": {
"next_cursor": "sc.eyJ2IjoyLCJjIjoiMiIsInAiOiJwYWdlIn0",
"has_more": true,
"page_size": 30,
"stopped_at": "known_id"
}
}Changes
No recorded changes to this operation across all 1 revision of this API.