Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ZemerTeam/zemer-cipher/llms.txt
Use this file to discover all available pages before exploring further.
PoTokenGenerator generates BotGuard proof-of-origin (PoToken) pairs for YouTube’s web client. It runs the BotGuard JavaScript challenge inside an Android WebView (via PoTokenWebView) and returns a PoTokenResult containing both a session-bound token for InnerTube requests and a video-bound token for CDN stream URLs.
Package: com.zemer.cipher.potoken
PoTokenGenerator is not a singleton — create one instance per use-case. Each instance manages a single PoTokenWebView internally and tracks the current session state.
Constructor
WebView until getWebClientPoToken is first called.
Functions
getWebClientPoToken
PoTokenResult containing both BotGuard tokens. This is a blocking call.
The YouTube video ID (e.g.
dQw4w9WgXcQ). Used to generate the video-bound streamingDataPoToken. The CDN validates that this token is bound to the specific video ID — using a token minted for a different video results in CDN truncation past ~1 MiB.The visitor’s
visitorData string from an InnerTube API response. Used to generate the session-bound playerRequestPoToken. The session token is minted once per sessionId and reused across videos — the WebView is only recreated when the sessionId changes, when the existing token expires, or when the renderer dies.A
PoTokenResult holding both tokens on success, or null in the following cases:- The device does not support
WebView(webViewSupported = false) - The system
WebViewhas a broken implementation (aBadWebViewExceptionwas raised — permanently flagged for this instance; all subsequent calls will also returnnull) - Generation times out after 8 seconds (
POTOKEN_TIMEOUT_MS = 8_000L)
PoTokenException— A JavaScript-level error that persists even after theWebViewis recreated and the operation retried. This indicates a durable failure (e.g. BotGuard script changes) rather than a transient one.
generatePoToken(videoId) call fails and the PoTokenWebView has not already been freshly recreated in this call, the function retries once by closing and fully recreating the PoTokenWebView from scratch — including re-minting the session token. If that retry also fails, the exception propagates (as PoTokenException or another throwable). Failures during session-token generation or on a freshly recreated WebView are not retried.
Timeout and cleanup: If generation exceeds 8 seconds (which can happen when the sandboxed WebView renderer is culled by the OS under memory pressure), the call returns null and the PoTokenWebView is closed and reset so the next call starts fresh.
WebView lifecycle: The internal PoTokenWebView is recreated automatically when:
sessionIdchanges- The existing WebView reports it has expired (
isExpired) - The renderer has died (
isDead— OOM kill by the OS) forceRecreateis triggered by an internal retry
Constants
| Constant | Value | Description |
|---|---|---|
POTOKEN_TIMEOUT_MS | 8_000L | Maximum milliseconds to wait for token generation before returning null. Cold-start (WebView spin-up + BotGuard JS load + token mint) typically takes 2–5 seconds. |
Example
Exceptions
PoTokenException
BadWebViewException (which disables the WebView for this instance permanently).
BadWebViewException
WebView returns a SyntaxError from the BotGuard JS. This indicates the installed system WebView is fundamentally broken (e.g. an outdated or corrupt WebView APK). Once caught, the PoTokenGenerator instance sets webViewBadImpl = true and all subsequent calls to getWebClientPoToken immediately return null.