[!TIP] TL;DR recommended setup: Either use a plugin, or manual extraction, to provide the
web
client with a PO Token for GVS requests.See the notice in the YouTube Extractor Wiki for more information on the current state of downloading videos from YouTube.
Proof of Origin (PO) Token is a parameter that YouTube requires to be sent with requests from some clients. Without it, requests for the affected clients' format URLs may return HTTP Error 403, or result in your account or IP address being blocked.
A PO Token is generated by an attestation provider on Web, Android and iOS platforms to attest the requests are coming from a genuine client.
For yt-dlp, you can provide PO Token(s) using the po_token
extractor argument, or you can install a plugin that hooks into the YouTube extractor to handle fetching a PO Token.
For more technical details on these tokens, refer to the technical details section.
There are currently two cases yt-dlp may require PO Tokens for video downloads, depending on the client used:
player
requestsThe PO Tokens may be generated differently for each of these cases, depending on the client.
YouTube is at present rolling out changes to enforce PO Tokens for video playback. Currently, only GVS requires PO Tokens for some clients.
Client | PO Token for GVS Required | PO Token for Player Required | Notes |
---|---|---|---|
web |
Yes | No | |
web_safari |
Yes* | No | |
mweb |
Yes | No | |
tv |
No | No | |
tv_embedded |
No | No | Requires account cookies |
web_embedded |
No | No | |
web_music |
Yes | No | |
web_creator |
Yes | No | Requires account cookies |
android |
Yes | ? | Account cookies not supported |
android_vr |
No | No | YouTube Kids videos are not available |
ios |
Yes* | ? | Account cookies not supported |
*Client provides HLS (m3u8) formats which do not require PO Token for GVS at this time.
You can select what client to use with the player_client
extractor argument.
web
client)This section provides a basic guide on extracting PO Token(s) manually from YouTube in a web browser for use with the web
client, and manually passing it to yt-dlp via the po_token
extractor argument.
The same PO Token extraction method may work with other web browser-based clients too.
[!TIP] When supplying multiple PO Tokens, use the same extractor args option and comma-separate the PO Token configurations. For example:
--extractor-args "youtube:po_token=web.gvs+GVS_PO_TOKEN_VALUE_HERE,web.player+PLAYER_PO_TOKEN_VALUE_HERE"
The PO Token used for web
GVS requests is tied to your YouTube session. It generated differently depending on if you are logged in to yt-dlp or not.
>>
button if you don't see it)googlevideo.com
googlevideo.com
should appear in the network tabgooglevideo.com
request, extract the pot
query parameter value from the URL--extractor-args "youtube:po_token=web.gvs+PO_TOKEN_VALUE_HERE"
with cookies (--cookies COOKIES_FILE
or --cookies-from-browser
)Although not recommended, you may also provide visitor data instead of cookies. Refer to Passing Visitor Data without cookies.
--extractor-args "youtube:po_token=web.gvs+PO_TOKEN_VALUE_HERE"
with your account cookies Addendum:
pot
parameter in the googlevideo.com
URL, wait a few seconds for more requests to be made and check them.sabr=1
query parameter in the googlevideo.com
URL, then the PO Token is in the request body protobuf (and therefore is not easy to extract).
The PO Token for web
Player requests is tied to the Video ID. This means you must generate a new PO Token for each video.
[!NOTE] If you are using the
web
client and have not disabled thewebpage
request, providing this PO Token is not necessary at this time.
v1/player
serviceIntegrityDimensions.poToken
and save that value--extractor-args "youtube:po_token=web.player+PO_TOKEN_VALUE_HERE"
Manually fetching PO Tokens can be a tedious process. Alternatively, you can use a plugin that hooks into the YouTube extractor to handle fetching a PO Token.
See the yt-dlp-plugins GitHub topic and the yt-dlp plugin wiki to explore more yt-dlp plugins.
PO Tokens are still an active area of research, and at the same time YouTube is continuously updating the implementation and enforcement. The following information is based on the current understanding of PO Tokens, and is subject to change.
A PO Token is generated by either BotGuard (Web), DroidGuard (Android), iOSGuard (iOS). A PO Token from one platform cannot be used on another (i.e., Web PO Token cannot be used on Android or iOS).
If you are interested, we recommend checking out the BgUtils project which does a deeper dive into the BotGuard attestation process.
GVS uses a PO token bound to the user session.
For Web session tokens:
VISITOR_INFO1_LIVE
cookie, in the visitorData
value which is sent with Innertube API requests, or with ytcfg.get('VISITOR_DATA')
in the browser console.responseContext.mainAppWebResponseContext.dataSyncId
in Innertube responses, or with ytcfg.get('DATASYNC_ID')
in the browser console.If a video download fails with an HTTP 403 midway through, then the client likely requires a PO Token for GVS.
These PO Tokens are only valid for a limited time (usually at least 12 hours), so it will need to be refreshed periodically. However, some reports suggest that the token may be valid for many days.
Web Tokens for player requests are bound to the video ID the associated /player
request is for. YouTube has only recently started generating these for some clients (e.g. web
).
As of writing, some clients, such as web_music
use a session-bound PO Token for player requests. This is likely to change.