-
-
Notifications
You must be signed in to change notification settings - Fork 12
YouTube API Features
Created in 2015, InnerTube is a cross-platform API created to simplify the deployment of updates and experiments across the platform. This is not confused with the YouTube Data API, which is the publicly available, officially supported API for programmatic use
This page documents Innertube to help contributors get up to speed with API and its known features. This page will be updated periodically as the reverse engineering process continues.
🚧This page is currently under construction, not all features are included here at the moment🚧
To obtain an API key, send a get request to https://youtube.com/sw.js_data
. The API key will be a 39-character string often beginning with the string AIza
This is a standard context object. The context object will be needed for most API calls to Innertube, this will only need to be created once per session as the context object doesn't change. Note: All the examples in this page will use an abbreviated version of the context object.
{
"client": {
"gl": "US",
"hl": "en-US",
"deviceMake": "Generic",
"userAgent": "Dalvik/2.1.0 (Linux; U; Android 12; sdk_gphone64_x86_64 Build/SE1A.220203.002.A1),gzip(gfe)",
"clientVersion": "18.06.35",
"clientName": "ANDROID",
"osName": "ANDROID",
"osVersion": "12",
"platform": "MOBILE",
"visitorData": "CgtZZFRBc1VkVmthayiow_uUBg%3D%3D",
"clientFormFactor": "SMALL_FORM_FACTOR"
}
}
Let's take a look at what all these values mean
- gl: the ISO-3166-1 Alpha 2 code for the location of the user. The default value can be obtained in the sw.js_data endpoint.
- hl: the ISO 639-1 code for the language. May also be trailed by an all caps ISO-3166-1 Alpha 2 country code for languages with regional differences (i.e en-US). The default value can be obtained in the sw.js_data endpoint.
- userAgent: a random user agent
- clientName & clientVersion: the API types & version
-
visitorData: a protobuf encoded 11-character random string and the current UNIX timestamp in seconds, replacing the
+
and/
with the-
and_
characters respectively. This can also be obtained in the sw.js_data endpoint. - devicemake, osName, osVersion, platform & clientFormFactor: data about the device. Can be hard coded.
Client Name | Version |
---|---|
ANDROID | 18.06.35 |
WEB | 2.20230206.06.00 |
MWEB | 2.20230206.06.00 |
to retrieve the home page, simply send a post request to the https://www.youtube.com/youtubei/v1/browse
endpoint.
this request supports pagination. See Continuations.
curl --request POST \
--url 'https://www.youtube.com/youtubei/v1/browse?key=AIzaSyDCU8hByM-4DrUqRUYnGn-3llEO78bcxq8' \
--header 'Content-Type: application/json' \
--data '{
"context": {
"client": {
"clientName": "ANDROID",
"clientVersion": "18.06.35",
"hl": "en-US"
}
},
"browse_id": "FEwhat_to_watch"
}'
To search for a given query, use the https://www.youtube.com/youtubei/v1/search
endpoint
this request supports pagination. See Continuations.
curl --request POST \
--url 'https://www.youtube.com/youtubei/v1/search?key=AIzaSyDCU8hByM-4DrUqRUYnGn-3llEO78bcxq8' \
--header 'Content-Type: application/json' \
--data '{
"context": {
"client": {
"clientName": "ANDROID",
"clientVersion": "18.06.35",
"hl": "en-US"
}
},
"query": "Linus Tech Tips"
}'
Search filters are represented in the request by a protobuf-encoded string under the params
key. The protobuf schema is as follows:
message SearchFilter {
optional int32 sort = 1; // int representing how to sort the search results. relevance: 0, rating: 1, upload date: 2, view count: 3
optional int32 noCorrection = 8;
optional int32 noFilter = 19; // Set to 1 if the there's no filters. Otherwise, set to null.
message Filters {
optional int32 param_0 = 1; // int representing the upload date. all time: null, hour: 1, day: 2, week: 3, month: 4, year: 5. Conflicts with channel and playlist filters
optional int32 param_1 = 2; // int representing the type filtered. all: null, video: 1, channel: 2, playlist: 3, movie: 4
optional int32 param_2 = 3; // int representing the duration filtered. all: null, under 4 mins: 1, 4-20 mins: 2, >20 mins: 3. Conflicts with channel and playlist filters
// type filters. Conflicts with channel and playlist filters
optional int32 featuresHd = 4; // hd filter. 0 for true, 1 for false.
optional int32 featuresSubtitles = 5; // subtitles filter. 0 for true, 1 for false.
optional int32 featuresCreativeCommons = 6; // creative commons filter. 0 for true, 1 for false.
optional int32 features3d = 7; // 3d filter. 0 for true, 1 for false.
optional int32 featuresLive = 8; // live filter
optional int32 featuresPurchased = 9; // purchased filter
optional int32 features4k = 14; // 4k filter
optional int32 features360 = 15; // 360 view filter. Conflicts with vr180
optional int32 featuresLocation = 23; // filter videos with location tags
optional int32 featuresHdr = 25; // hdr filter
optional int32 featuresVr180 = 26; // vr180 filter. Conflicts with 360 degrees
}
optional Filters filters = 2; // put filter object here
}
To retrieve a given playlist, first, identify the playlist's ID. In a URL this will be the code after ?list=
. For example, https://www.youtube.com/playlist?list=PLB7ZcpBcwdC7rGYl6StHarkLlgeZX66oL
's ID will be PLB7ZcpBcwdC7rGYl6StHarkLlgeZX66oL
. Playlist IDs will always begin with the string VLPL
(case sensitive). For IDs retrieved from URLs, this will mean that you need to prepend VL
to the ID.
The call the /browse
endpoint with the value of the browse_id
key being the ID
this request supports pagination. See Continuations. /browse
endpoint
curl --request POST \
--url 'https://www.youtube.com/youtubei/v1/browse?key=AIzaSyDCU8hByM-4DrUqRUYnGn-3llEO78bcxq8' \
--header 'Content-Type: application/json' \
--data '{
"context": {
"client": {
"clientName": "ANDROID",
"clientVersion": "18.06.35",
"hl": "en-US"
}
},
"browse_id": "VLPLB7ZcpBcwdC7rGYl6StHarkLlgeZX66oL"
}'
For any features or segments that support infinite pagination, there will be a continuations
array which contains a nextContinuationData
object that contains a long string with the key continuation
.
Simply call the https://youtube.com/youtubei/v1/next
endpoint with the continuation string to paginate
curl --request POST \
--url 'https://www.youtube.com/youtubei/v1/next?key=AIzaSyDCU8hByM-4DrUqRUYnGn-3llEO78bcxq8' \
--header 'Content-Type: application/json' \
--data '{
"context": {
"client": {
"clientName": "ANDROID",
"clientVersion": "18.06.35",
"hl": "en-US"
}
},
"continuation": "4qmFsgL6AhIPRkV3aGF0X3RvX3dhdGNoGuYCQ0FWNi13RkhUVkJHYm5aWFpXMTJaME5OWjNOSmFuSlhZWEU0WmpKd05IVmZRVlp3ZFVOdGQwdEhXR3d3V0ROQ2FGb3lWbVpqTWpWb1kwaE9iMkl6VW1aamJWWnVZVmM1ZFZsWGQxTklNRlV3VG0xc01HUldaSEZUVmtWM1ZWVkdSVkV5TVRKaldFWlpXVEpLZUUxdVduQk1VekZHWlVkallVeG5RVUZhVnpSQlFWWldWRUZCUms5WFowRkNRVVZhUm1ReWFHaGtSamt3WWpFNU0xbFlVbXBoUVVGQ1FVRkZSRUZSUlVGQlVVRkNRVUZCUWtGUlFtbE1RV2RCUldoT2QxbFhaR3hZTTA1MVdWaENlbUZIT1RCWU0xSjJZVEpXZFVkb1RVbHlZMjFCT1ZvMllTMUJTVlpvYjBwcVFtZ3pjblozZWxNdGNIcElkbEZyUTBOQlk4Z0dBZm9HQkFvQ0NBVSUzRA%3D%3D"
}'