Documentation Index
Fetch the complete documentation index at: https://mintlify.com/faraasaaay/innertube-v2/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Every request InnerTube sends to YouTube’s API includes a client context — a JSON object that tells YouTube which app is making the request.YouTubeClient is a @Serializable data class that represents this identity and drives the HTTP headers that accompany every call.
Key Fields
| Field | Description |
|---|---|
clientName | The X-YouTube-Client-Name header and context.client.clientName body field. |
clientVersion | The X-YouTube-Client-Version header and context.client.clientVersion body field. |
clientId | Numeric ID sent in the X-YouTube-Client-Name header (YouTube uses the numeric ID in that header despite its name). |
userAgent | The User-Agent HTTP header, mimicking the real app or browser. |
loginSupported | When true, authentication cookies and SAPISIDHASH are attached to requests for this client. |
loginRequired | When true, the client only works when the user is signed in. |
useSignatureTimestamp | When true, InnerTube fetches a signature timestamp (via NewPipe) and includes it in the PlayerBody.PlaybackContext. Required for WEB-based stream decryption. |
isEmbedded | When true, the request body includes a thirdParty.embedUrl — allows bypassing some age restrictions. |
useWebPoTokens | When true, a PoToken must be generated and appended to the stream URL. Required for WEB and WEB_REMIX stream resolution. |
toContext() — Building the Request Body
YouTubeClient.toContext() produces the Context object that is embedded in every API request body:
Context includes:
client— clientName, clientVersion, OS info, device info, locale (gl/hl), visitorDatauser.onBehalfOfUser— set todataSyncIdonly whenloginSupported = truerequest—useSsl: true(always)
InnerTube calls toContext() automatically when building each request body. You do not need to call it manually.
Named Client Constants
All predefined clients are available as constants inYouTubeClient.Companion. Select the right one for your use case:
Client Reference Table
| Constant | loginSupported | useWebPoTokens | Notes |
|---|---|---|---|
WEB | ❌ | ❌ | Standard YouTube web client. Used for comments(), transcript(), and next(). |
WEB_REMIX | ✅ | ✅ | YouTube Music web client. The default for almost all music browse and search calls. Requires signature timestamp for playback. |
WEB_CREATOR | ✅ (loginRequired) | ❌ | YouTube Studio client. Used for age-restricted content when the user is signed in. |
TVHTML5 | ✅ (loginRequired) | ✅ | Smart TV client. Supports PoTokens. Used in stream fallback chain. |
TVHTML5_SIMPLY_EMBEDDED_PLAYER | ✅ | ❌ | Embedded player (isEmbedded = true). Can bypass age restrictions without login. First fallback for age-restricted streams. |
IOS | ❌ | ❌ | iOS YouTube app. No login support. |
IPADOS | ❌ | ❌ | iPadOS YouTube app. iPad 6th Gen device model. No AV1 hardware decoding. |
MOBILE | ✅ | ❌ | Android YouTube app (ANDROID client name). Login and signature timestamp supported. |
ANDROID_NO_SDK | ❌ | ❌ | Android client without SDK context. No auth, no signature. Cannot play paid, private, or age-restricted content. |
ANDROID_VR_NO_AUTH | ❌ | ❌ | Android VR v1.61 without auth headers. No login, no signature. |
ANDROID_VR_1_61_48 | ❌ | ❌ | Android VR v1.61 with full device context (Oculus Quest 3). Can play most content. Not usable when logged in. |
ANDROID_VR_1_43_32 | ❌ | ❌ | Android VR v1.43. Uses non-adaptive bitrate (fixes audio stuttering). Does not use AV1. Primary client for audio playback. |
ANDROID_CREATOR | ✅ | ❌ | YouTube Creator app. Can play videos for children and with music; cannot play live streams or HDR. |
VISIONOS | ❌ | ❌ | Internal visionOS client (clientId = 101). Experimental — may stop working at any time. |
ANDROID_MUSIC | ✅ | ❌ | Android YouTube Music app. Login and signature timestamp supported. |
IOS_MUSIC | ✅ | ❌ | iOS YouTube Music app. Login and signature timestamp supported. |
Passing a Client to YouTube.player()
Most high-level YouTube.* methods choose their client internally. The player() method is the primary place where you explicitly pass a YouTubeClient:
Multi-Client Fallback Strategy
In practice, no single client can play every video.YTPlayerUtils implements a robust waterfall strategy:
Primary client (fast path):
ANDROID_VR_1_43_32 is tried first for every video. It does not require a PoToken and resolves streams with minimal latency. Its non-adaptive bitrate also eliminates an audio-stuttering issue present in newer VR client versions.
Fallback chain (on failure):
- If the primary client’s
playabilityStatus.statusis not"OK", the next client in the array is tried. - Clients with
loginRequired = trueare skipped automatically when the user is not signed in. - PoTokens are generated lazily — only when a web client (with
useWebPoTokens = true) is actually reached in the chain. - For age-restricted content,
TVHTML5_SIMPLY_EMBEDDED_PLAYERis tried before login-gated clients. - Stream URLs from web clients are processed through an n-transform deobfuscation step before being validated with a lightweight
HEADrequest.