Unofficial YouTube Studio API. Set of features limited or not provided by official YouTube API
BEWARE: API will change during upcomming releases
- setting monetisation
- uploading video (NOT LIMITED - official API's
videos.insertcharges you 1600 quota units) - setting / getting endscreen
- setting info cards
- getting video claims
- getting video details
- setting video comment options
$ npm i -SE youtube-studioconst{ init, setMonetisation }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constresult=awaitsetMonetisation({encryptedVideoId: 'hHbWF1Bvgf4',// your video IDmonetizationSettings: {newMonetizeWithAds: true// Monetisation: On},adFormats: {// Type of adsnewHasOverlayAds: 'ENABLED',// Overlay adsnewHasProductListingAds: 'ENABLED',// Sponsored cardsnewHasSkippableVideoAds: 'DISABLED',// Skippable video adsnewHasNonSkippableVideoAds: 'ENABLED',// Non-skippable video ads},adBreaks: {// Location of video adsnewHasPrerolls: 'DISABLED'// Before videonewHasMidrollAds: 'DISABLED',// During videonewHasManualMidrolls: 'DISABLED',// Manual placement (not yet provided)newHasPostrolls: 'ENABLED',// After video},})console.log(result)Official API's videos.insert resource charges you 1600 quota units per single video upload.
constfs=require('fs')const{ init, upload }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constresult=awaitupload({channelId: 'UCzQUP1qoWDoEbmsQxvdjxgQ',// your channelIdstream: fs.createReadStream('./example=video.mp4'),// your video streamnewTitle: 'new video 1',// optional, your video namenewDescription: 'Please, subscribe!',// optional, your video descriptionnewPrivacy: 'PRIVATE',// optional (PRIVATE by default), ('PUBLIC', 'UNLISTED', 'PRIVATE' options available)isDraft: false,// optional, video can be a draft (false by default)})console.log(result)Full example with 'progress' feature available in /examples/upload.js
const{ init, setEndScreen, endScreen }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constvideoLengthSec=1404constTWENTY_SEC_BEFORE_END_MS=(videoLengthSec-20)*1000constresult=awaitsetEndScreen(VIDEO_ID,TWENTY_SEC_BEFORE_END_MS,[{ ...endScreen.TYPE_RECENT_UPLOAD},// recent upload in top left position{ ...endScreen.POSITION_BOTTOM_RIGHT, ...endScreen.TYPE_SUBSCRIBE(CHANNEL_ID)},// subscribe button{ ...endScreen.POSITION_TOP_RIGHT, ...endScreen.TYPE_BEST_FOR_VIEWERS, ...endScreen.DELAY(500)},// best for viewers delayed with 0.5 sec{ ...endScreen.POSITION_BOTTOM_LEFT, ...endScreen.TYPE_PLAYLIST(PLAYLIST_ID), ...endScreen.DELAY(1000)}// playlist delayed with 1 sec])console.log(result)const{ init, getEndScreen }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constresult=awaitgetEndScreen(VIDEO_ID)console.log(result.endscreens[0].elements)// see more in unit testsconst{ init, setEndScreen, endScreen }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constresult=awaitgetVideo(VIDEO_ID)constvideo=result.videos[0]console.log(video.status)// VIDEO_STATUS_PROCESSEDconsole.log(video.monetization.adMonetization.effectiveStatus)// VIDEO_MONETIZING_STATUS_MONETIZING_WITH_LIMITED_ADSconsole.log(video.lengthSeconds)// '1404'console.log(video.watchUrl)// '1404'const{ init, setInfoCards }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constresult=awaitsetInfoCards(VIDEO_ID,[{playlistId: PLAYLIST_ID,teaserStartMs: 15000,customMessage: 'Check this one:',teaserText: 'If you need more...'}])const{ init, getVideoClaims }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constresult=awaitgetVideoClaims(CLAIMS_VIDEO_ID)consthumanizedClaims=result.receivedClaims.map(claim=>{constaudio=claim.asset.metadata.soundRecordingconsttimestamp=claim.matchDetailsreturn`"${audio.title}", by ${audio.artists.join(', ')} (starting at ${timestamp.longestMatchStartTimeSeconds} sec.)`})console.log(humanizedClaims)// ['"Fasl", by Kabul Dreams (starting at 2771 sec.)', ...]const{ init, setCommentOptions }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constresult=awaitsetCommentOptions({encryptedVideoId: 'hHbWF1Bvgf4',// your video IDcommentOptions: {newAllowCommentsMode: "ALL_COMMENTS",// or "AUTOMATED_COMMENTS" or "APPROVED_COMMENTS" or "UNKNOWN_COMMENT_ALLOWED_MODE",newAllowComments: true,// should be "false" for newAllowCommentsMode="UNKNOWN_COMMENT_ALLOWED_MODE"newCanViewRatings: true,// Show how many viewers like and dislike this videonewDefaultSortOrder: "MDE_COMMENT_SORT_ORDER_LATEST"// or "MDE_COMMENT_SORT_ORDER_TOP"}})console.log(result)const{ init, setCommentOptions }=require('youtube-studio')awaitinit({ ... })// read more below (Preparing Authentication)constresult=awaitsetCommentOptions({encryptedVideoId: 'hHbWF1Bvgf4',commentOptions: {newAllowCommentsMode: "UNKNOWN_COMMENT_ALLOWED_MODE",newAllowComments: false,newCanViewRatings: true,// Show how many viewers like and dislike this videonewDefaultSortOrder: "MDE_COMMENT_SORT_ORDER_LATEST"}})console.log(result)It's recommended to do it in a browser's private mode.
IMPORTANT: you need to filter cookies by .youtube.com domain.
Here's a list of required cookies:
SIDHSIDSSIDAPISIDSAPISIDLOGIN_INFO(if available)
...like here:
If you plan to use setMonetisation() or upload() or setEndScreen() functions, you need to have SESSION_TOKEN.
IMPORTANT: Keep in mind, that you need to regenerate this value each day.
Use your dev tools to get the value of SESSION_TOKEN (/grst API):
const{ init, getVideo }=require('youtube-studio')(async()=>{awaitinit({SID,HSID,SSID,APISID,SAPISID,LOGIN_INFO,// specify, if available in your cookiesSESSION_TOKEN// this is optional, see point 3. above})// you can authenticate once!constvideo=awaitgetVideo('your video id')console.log(video)}())
