BetterYTS API
Free, keyless and CORS-enabled. Every result comes back with ads, promoted videos and filler shelves already stripped out.
💡 Base URL
All endpoints live on https://yts.foulfoxhacks.dev. Prefer the browser? The search page runs on this same API.
VRChat & media-player redirects
Paste any of these into a video player such as ProTV, USharpVideo or iwaSync. Each one answers with an HTTP 302 to the matching YouTube video, and the player takes it from there.
https://yts.foulfoxhacks.dev/search?q=lofi hip hop
https://yts.foulfoxhacks.dev/search?=lofi hip hop # same thing
https://yts.foulfoxhacks.dev/search?lofi+hip+hop # same thing
https://yts.foulfoxhacks.dev/lofi hip hop # u2b.cx-style shortcut
https://yts.foulfoxhacks.dev/lucky?q=lofi&n=2 # 2nd result, always redirects
https://yts.foulfoxhacks.dev/v/dQw4w9WgXcQ # by video ID
In a normal browser tab, /search shows the results page instead. Add &lucky to force the redirect. If the query is a YouTube link, you go straight to that video.
⚠️ Untrusted URLs
VRChat only plays URLs from its trusted list unless Allow Untrusted URLs is on in Comfort & Safety settings. That applies to every custom search domain, u2b.cx included.
Redirect options
| Option | Default | What it does |
|---|---|---|
n | 1 | Play the nth result (1–20). |
shorts | 0 | Allow Shorts to be picked. |
live | 1 | Allow live streams to be picked (live=0 skips them). |
minlen / maxlen | — | Only pick videos at least / at most this many seconds long. |
sort | relevance | relevance, date, views, rating |
duration | — | short (<4 min), medium (4–20), long (>20) |
upload | — | hour, today, week, month, year |
features | — | Comma list: hd, 4k, live, subtitles, cc, hdr, 360, vr180, 3d |
to | watch | Redirect target: watch (youtube.com), youtu.be, embed (youtube-nocookie), music |
hl / gl | en / US | Language and region of the search. |
GET/api/search
GET /api/search?q=minecraft+music&type=video&sort=views
| Param | Values |
|---|---|
q | Search text (max 200 chars). ?= and bare ?term also work. |
type | all (default), video, channel, playlist, movie |
sort, duration, upload, features | Same as the redirect options. |
shorts | 1 (default) keeps Shorts mixed into results, 0 removes them. |
shelves | 0 (default) drops "People also watched", Shorts shelves and similar filler; 1 keeps them, tagged with shelf. |
dearrow | 1 attaches DeArrow titles and thumbnails to each video as branding. |
page | The next token from a previous response. |
hl, gl | Language and region. |
{
"query": "minecraft music",
"correctedQuery": null,
"estimatedResults": 1830000,
"count": 20,
"results": [
{
"type": "video", // video | short | channel | playlist | mix
"id": "qq-RGFyaq0U",
"url": "https://www.youtube.com/watch?v=qq-RGFyaq0U",
"title": "…",
"thumbnail": "https://i.ytimg.com/vi/…/hq720.jpg",
"duration": "1:02:51", "durationSeconds": 3771,
"views": "12,345,678 views", "viewCount": 12345678,
"published": "2 years ago",
"description": "…",
"channel": { "name": "…", "id": "UC…", "url": "…", "handle": "@…", "verified": true, "avatar": "…" },
"badges": ["4K"], "live": false, "upcoming": false, "isShort": false
}
],
"next": "EpEDEg9taW5lY3JhZnQ…", // pass back as ?page=
"blocked": { "ads": 2, "shorts": 0, "shelfItems": 9 }
}
GET/api/video/{id}
Everything about one video in a single call, with the community add-ons merged in.
{
"id": "dQw4w9WgXcQ",
"title": "…", "author": "…", "channelId": "UC…", "channelUrl": "…",
"lengthSeconds": 213, "viewCount": 1837613210,
"description": "…", "keywords": ["…"], "publishDate": "2009-10-24T23:57:33-07:00", "category": "Music",
"embed": "https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ",
"sponsorblock": [ { "category": "sponsor", "action": "skip", "start": 12.5, "end": 41.0, "uuid": "…", "votes": 12, "locked": false } ],
"votes": { "likes": 18000000, "dislikes": 240000, "rating": 4.9, "viewCount": 1837613210, "deleted": false },
"dearrow": { "title": "…", "thumbnail": "https://dearrow-thumb.ajay.app/…", "thumbnailTime": 42.1 }
}
Add-on endpoints
GET/api/segments/{id}
SponsorBlock segments. BetterYTS looks them up through SponsorBlock's hash-prefix API, so SponsorBlock never sees exactly which video you asked about. Filter with ?categories=sponsor,intro.
Categories: sponsor, selfpromo, exclusive_access, interaction, intro, outro, preview, hook, filler, music_offtopic, poi_highlight, chapter.
GET/api/dislikes/{id}
Likes and estimated dislikes from Return YouTube Dislike.
GET/api/branding/{id}
DeArrow's community title and thumbnail, or null. For many videos at once, use /api/branding?ids=a,b,c (up to 30 IDs). It returns an object keyed by ID.
GET/api/suggest
Autocomplete suggestions for ?q=, as a plain JSON array of strings.
Errors & caching
Errors use normal HTTP status codes and a JSON body:
{ "error": { "status": 400, "message": "Missing search query. Use /api/search?q=your+search" } }
Responses are cached at Cloudflare's edge for 5–30 minutes. The X-Cache header shows whether a response was a HIT or a MISS.
Fair use & credits
- Please cache on your side too, and don't hammer the API.
- SponsorBlock and DeArrow data is © their contributors under CC BY-NC-SA 4.0: non-commercial use, with attribution.
- Dislike counts are estimates from Return YouTube Dislike.
- BetterYTS is not affiliated with YouTube or Google. Source: github.com/foulfoxhacks/betteryts.