Skip to content
This repository has been archived by the owner on Aug 25, 2024. It is now read-only.

YouTube API Features

Alex edited this page Feb 12, 2023 · 7 revisions

The YouTube API

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🚧

Initialisation

Obtaining an API Key

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

Context

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.

API types & version

Client Name Version
ANDROID 18.06.35
WEB 2.20230206.06.00
MWEB 2.20230206.06.00

The Home Page

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"
}'

Search

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"
}'

Filters

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
}

Playlist

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. ⚠️ Note: the pagination endpoint for playlists is the /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"
}'

Continuations

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"
}'