Inner operates in two modes. In anonymous mode it attaches only aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/faraasaaay/inner/llms.txt
Use this file to discover all available pages before exploring further.
visitorData string as X-Goog-Visitor-Id and can read most public content — home feed, search, albums, artists, and playlists. In authenticated mode it additionally sends a session cookie and a signed Authorization: SAPISIDHASH header, unlocking library management, playback history, like/subscribe actions, and personalised recommendations.
Anonymous browsing
Anonymous requests are identified by avisitorData string — a base64-encoded protobuf token YouTube uses for session continuity and recommendation context. YouTube fetches it from the sw.js bootstrap endpoint.
visitorData updates the internal PlaybackAuthState and causes it to be sent as the X-Goog-Visitor-Id header on every subsequent request. If visitorData is null, requests are sent without the header.
Cookie-based authentication
To authenticate, you need the rawCookie header from an active YouTube Music browser session.
Open YouTube Music in your browser
Navigate to music.youtube.com and sign in to the account you want to use.
Open DevTools Network tab
Press F12 → Network tab. Reload the page or click any element to trigger a request.
Copy the Cookie header
Find any request to
music.youtube.com. In the Request Headers section, copy the full value of the Cookie header. It will contain keys like SAPISID, __Secure-3PSID, __Secure-3PAPISID, and others.SAPISID is set, YouTube.hasLoginCookie() returns true. If both a cookie and a non-blank dataSyncId are present, YouTube.hasPlaybackLoginContext() returns true, enabling full personalised playback context.
SAPISIDHASH signing
Inner automatically generates a signedAuthorization header for every authenticated request — you never need to construct it yourself.
The buildSapisidAuthorization function in RequestMetadata.kt computes:
<timestamp> is the current Unix time in seconds, <SAPISID> is the value extracted from the cookie string, and <origin> is either https://music.youtube.com (for most clients) or https://www.youtube.com (for TV clients). The SHA-1 is computed using Inner’s pure-Kotlin implementation in CommonAuthUtils.kt.
This header is only attached when setLogin = true and the target YouTubeClient has loginSupported = true.
PlaybackAuthState
PlaybackAuthState is the single data class that holds all authentication context. It is immutable — every setter on YouTube creates a new normalised copy.
| Field | Type | Purpose |
|---|---|---|
cookie | String? | Raw Cookie header string sent with authenticated requests |
visitorData | String? | Value of the X-Goog-Visitor-Id header |
dataSyncId | String? | Used as onBehalfOfUser in the InnerTube request context |
poToken | String? | Generic PoToken fallback when no specialised token is set |
poTokenGvs | String? | Token appended as ?pot= to GVS stream URLs |
poTokenPlayer | String? | Token placed in serviceIntegrityDimensions for player requests |
webClientPoTokenEnabled | Boolean | Master switch — PoTokens are only resolved when this is true |
PlaybackAuthState reflect login status:
hasLoginCookie—truewhen the cookie string contains aSAPISIDkey (determined by parsing the cookie into key-value pairs). This is the minimum requirement for attaching login headers.hasPlaybackLoginContext—truewhenhasLoginCookieistrueanddataSyncIdis non-blank. Required for personalised playback and library operations.
sessionId— returnsdataSyncIdwhenhasPlaybackLoginContextistrue, otherwise returnsvisitorData. Use this as the identifier for PoToken generation.fingerprint— a SHA-1 digest of all auth fields joined by\u0000(null character). Useful for detecting state changes without exposing raw credential values.
Using PlaybackAuthState
You can update individual fields via the convenience setters onYouTube, or replace the entire state atomically using YouTube.authState:
authState normalises all values (trims whitespace, strips "null" strings, handles ||-delimited dataSyncId formats) and propagates the new state to the internal InnerTube instance atomically. The current state is also exposed as a StateFlow<PlaybackAuthState> via YouTube.authStateFlow for reactive UI updates.
Proxy support
YouTube supports routing requests through an HTTP or SOCKS proxy via java.net.Proxy. Assigning a proxy recreates the underlying HttpClient with the new engine configuration. Proxy support is Android-only — PortableInnertube does not expose a proxy field.
streamBypassProxy is true, YouTube.streamProxy returns null, so stream URLs are fetched directly while all InnerTube API calls still go through the proxy.