{"id":15117406,"url":"https://github.com/adasq/youtube-studio","last_synced_at":"2025-09-27T23:30:50.478Z","repository":{"id":38105661,"uuid":"259020818","full_name":"adasq/youtube-studio","owner":"adasq","description":"Unofficial YouTube Studio API","archived":false,"fork":false,"pushed_at":"2024-02-19T11:54:54.000Z","size":2598,"stargazers_count":106,"open_issues_count":9,"forks_count":30,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-12-19T15:29:58.144Z","etag":null,"topics":["ad","ads","api","hacktoberfest","monetisation","studio","youtube","youtube-studio","yt"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adasq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-04-26T12:07:34.000Z","updated_at":"2024-12-12T17:05:51.000Z","dependencies_parsed_at":"2023-02-09T04:01:23.011Z","dependency_job_id":null,"html_url":"https://github.com/adasq/youtube-studio","commit_stats":null,"previous_names":[],"tags_count":25,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adasq%2Fyoutube-studio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adasq%2Fyoutube-studio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adasq%2Fyoutube-studio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adasq%2Fyoutube-studio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adasq","download_url":"https://codeload.github.com/adasq/youtube-studio/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234470271,"owners_count":18838628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ad","ads","api","hacktoberfest","monetisation","studio","youtube","youtube-studio","yt"],"created_at":"2024-09-26T01:45:56.608Z","updated_at":"2025-09-27T23:30:50.059Z","avatar_url":"https://github.com/adasq.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# youtube-studio\n![CI](https://github.com/adasq/youtube-studio/workflows/CI/badge.svg)\n[![NPM Downloads](https://img.shields.io/npm/dm/youtube-studio.svg?style=flat)](https://www.npmjs.org/package/youtube-studio)\n[![NPM Downloads](https://img.shields.io/npm/dt/youtube-studio.svg?style=flat)](https://www.npmjs.org/package/youtube-studio)\n\n\nUnofficial YouTube Studio API.\nSet of features **limited** or **not provided** by official YouTube API\n\n**BEWARE: API will change during upcomming releases**\n\n## Features\n- setting monetisation\n- uploading video (**NOT LIMITED** - official API's [`videos.insert`](https://developers.google.com/youtube/v3/determine_quota_cost) **charges you 1600 quota units**)\n- setting / getting endscreen\n- setting info cards\n- getting video claims\n- getting video details\n- setting video comment options\n\n## Installation\n\n```sh\n$ npm i -SE youtube-studio\n```\n\n## Setting monetisation\n\n```js\nconst { init, setMonetisation } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst result = await setMonetisation({\n    encryptedVideoId: 'hHbWF1Bvgf4', // your video ID\n    monetizationSettings: {\n        newMonetizeWithAds: true // Monetisation: On\n    },\n    adFormats: { // Type of ads\n        newHasOverlayAds: 'ENABLED', // Overlay ads\n        newHasProductListingAds: 'ENABLED', // Sponsored cards\n        newHasSkippableVideoAds: 'DISABLED', // Skippable video ads\n        newHasNonSkippableVideoAds: 'ENABLED', // Non-skippable video ads\n        \n    },\n    adBreaks: { // Location of video ads\n        newHasPrerolls: 'DISABLED' // Before video\n        newHasMidrollAds: 'DISABLED', // During video\n        newHasManualMidrolls: 'DISABLED', // Manual placement (not yet provided)\n        newHasPostrolls: 'ENABLED', // After video\n        \n    },\n})\n\nconsole.log(result)\n```\n\n## Uploading video\n\nOfficial API's [`videos.insert`](https://developers.google.com/youtube/v3/determine_quota_cost) resource **charges you 1600 quota units** per single video upload.\n\n```js\nconst fs = require('fs')\nconst { init, upload } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst result = await upload({\n    channelId: 'UCzQUP1qoWDoEbmsQxvdjxgQ', // your channelId\n    stream: fs.createReadStream('./example=video.mp4'), // your video stream\n\n    newTitle: 'new video 1', // optional, your video name\n    newDescription: 'Please, subscribe!', // optional, your video description\n    newPrivacy: 'PRIVATE', // optional (PRIVATE by default), ('PUBLIC', 'UNLISTED', 'PRIVATE' options available)\n    isDraft: false, // optional, video can be a draft (false by default)\n})\n\nconsole.log(result)\n```\n\nFull example with 'progress' feature available in [`/examples/upload.js`](https://github.com/adasq/youtube-studio/blob/master/examples/upload.js)\n\n## Setting endscreen\n\n```js\nconst { init, setEndScreen, endScreen } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst videoLengthSec = 1404\nconst TWENTY_SEC_BEFORE_END_MS = (videoLengthSec - 20) * 1000\n\nconst result = await setEndScreen(VIDEO_ID, TWENTY_SEC_BEFORE_END_MS, [\n    { ...endScreen.TYPE_RECENT_UPLOAD }, // recent upload in top left position\n    { ...endScreen.POSITION_BOTTOM_RIGHT, ...endScreen.TYPE_SUBSCRIBE(CHANNEL_ID) }, // subscribe button\n    { ...endScreen.POSITION_TOP_RIGHT,    ...endScreen.TYPE_BEST_FOR_VIEWERS,      ...endScreen.DELAY(500) }, // best for viewers delayed with 0.5 sec\n    { ...endScreen.POSITION_BOTTOM_LEFT,  ...endScreen.TYPE_PLAYLIST(PLAYLIST_ID), ...endScreen.DELAY(1000) } // playlist delayed with 1 sec\n])\n    \nconsole.log(result)\n```\n\n## Getting endscreen\n\n```js\nconst { init, getEndScreen } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst result = await getEndScreen(VIDEO_ID)\n    \nconsole.log(result.endscreens[0].elements) // see more in unit tests\n```\n\n## Getting video details\n\n```js\nconst { init, setEndScreen, endScreen } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst result = await getVideo(VIDEO_ID)\n\nconst video = result.videos[0]\n\nconsole.log(video.status) // VIDEO_STATUS_PROCESSED\nconsole.log(video.monetization.adMonetization.effectiveStatus) // VIDEO_MONETIZING_STATUS_MONETIZING_WITH_LIMITED_ADS\nconsole.log(video.lengthSeconds) // '1404'\nconsole.log(video.watchUrl) // '1404'\n```\n\n## Setting info cards\n\n```js\nconst { init, setInfoCards } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst result = await setInfoCards(VIDEO_ID, [{\n    playlistId: PLAYLIST_ID,\n    teaserStartMs: 15000,\n    customMessage: 'Check this one:',\n    teaserText: 'If you need more...'\n}])\n```\n\n## Getting video claims\n\n```js\nconst { init, getVideoClaims } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst result = await getVideoClaims(CLAIMS_VIDEO_ID)\n            \nconst humanizedClaims = result.receivedClaims.map(claim =\u003e {\n    const audio = claim.asset.metadata.soundRecording\n    const timestamp = claim.matchDetails\n    \n    return `\"${audio.title}\", by ${audio.artists.join(', ')} (starting at ${timestamp.longestMatchStartTimeSeconds} sec.)`\n})\n\nconsole.log(humanizedClaims) // ['\"Fasl\", by Kabul Dreams (starting at 2771 sec.)', ...]\n```\n\n## Setting video comment options\n### Enable all video comments\n```js\nconst { init, setCommentOptions } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst result = await setCommentOptions({\n    encryptedVideoId: 'hHbWF1Bvgf4', // your video ID\n    commentOptions: {\n        newAllowCommentsMode: \"ALL_COMMENTS\", // or \"AUTOMATED_COMMENTS\" or \"APPROVED_COMMENTS\" or \"UNKNOWN_COMMENT_ALLOWED_MODE\",\n        newAllowComments: true, // should be \"false\" for newAllowCommentsMode=\"UNKNOWN_COMMENT_ALLOWED_MODE\"\n        newCanViewRatings: true, // Show how many viewers like and dislike this video\n        newDefaultSortOrder: \"MDE_COMMENT_SORT_ORDER_LATEST\" // or \"MDE_COMMENT_SORT_ORDER_TOP\"\n    }\n})\n\nconsole.log(result)\n```\n### Disable video comments:\n```js\nconst { init, setCommentOptions } = require('youtube-studio')\n\nawait init({ ... }) // read more below (Preparing Authentication)\n\nconst result = await setCommentOptions({\n    encryptedVideoId: 'hHbWF1Bvgf4',\n    commentOptions: {\n        newAllowCommentsMode: \"UNKNOWN_COMMENT_ALLOWED_MODE\",\n        newAllowComments: false,\n        newCanViewRatings: true, // Show how many viewers like and dislike this video\n        newDefaultSortOrder: \"MDE_COMMENT_SORT_ORDER_LATEST\"\n    }\n})\n\nconsole.log(result)\n```\n\n## Preparing Authentication\n\n#### 1. Authenticate to studio.youtube.com\n\nIt's recommended to do it in a browser's **private mode**.\n\n#### 2. Open dev tools and copy specific cookie values\n\n**IMPORTANT**: you need to filter cookies by `.youtube.com` domain.\n\nHere's a list of required cookies:\n- `SID`\n- `HSID`\n- `SSID`\n- `APISID`\n- `SAPISID`\n- `LOGIN_INFO` (if available)\n\n...like here:\n\n![](docs/images/cookies.jpg)\n\n#### 3. Get `SESSION_TOKEN`\n\nIf you plan to use `setMonetisation()` or `upload()` or `setEndScreen()` functions, you need to have `SESSION_TOKEN`.\n\n**IMPORTANT**: Keep in mind, that you need to regenerate this value **each day**.\n\nUse your dev tools to get the value of `SESSION_TOKEN` (`/grst` API):\n\n![](docs/images/sessionToken.png)\n\n#### 4. Initialize your session:\n\n```js\nconst { init, getVideo } = require('youtube-studio')\n\n(async () =\u003e {\n    await init({\n        SID,\n        HSID,\n        SSID,\n        APISID,\n        SAPISID,\n        LOGIN_INFO, // specify, if available in your cookies\n        SESSION_TOKEN // this is optional, see point 3. above\n    }) // you can authenticate once!\n\n    const video = await getVideo('your video id')\n    console.log(video)\n}())\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadasq%2Fyoutube-studio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadasq%2Fyoutube-studio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadasq%2Fyoutube-studio/lists"}