YouTube Data API v3 · Playlists

Your playlist-builder tool works fine in testing — then the API key you shipped with rejects every write

playlists.insert and playlistItems.insert do not have an API-key path. Google's own reference documentation lists exactly three accepted authorization scopes for both methods, and an API key is not one of them. Anyone building a playlist curation tool, a save-to-playlist button, or a bulk playlist importer hits this wall the moment they move past reading data and try to write it.

What the reference pages actually require: both playlists.insert and playlistItems.insert must be authorized with at least one of youtubepartner, youtube, or youtube.force-ssl. There is no lighter-weight option. Every write to a playlist, no matter how small, needs a real OAuth 2.0 user consent flow — the same consent flow, and the same review exposure, as any other YouTube write operation.

What each method actually asks for

playlists.insert

  • Required: snippet.title
  • Optional: snippet.description, status.privacyStatus, snippet.defaultLanguage, localizations
  • Quota cost: 50 units per call
Creates a private, public or unlisted playlist in the authorized user's own channel — there is no way to create a playlist on a channel you do not control.

playlistItems.insert

  • Required: snippet.playlistId, snippet.resourceId (kind + videoId)
  • Optional: snippet.position, contentDetails.note (max 280 characters), contentDetails.startAt/endAt
  • Quota cost: 50 units per call
Adds one video per call. There is no batch-insert endpoint — a 50-video playlist costs 2,500 quota units to build, before you have added a single playlist of your own.

Why this sits inside Google's sensitive-scope review, not just an OAuth checkbox

Turning on OAuth is not the finish line. Google's own sensitive-scope documentation names deleting a YouTube video as its worked example of a sensitive scope — and youtube.force-ssl, one of the three scopes accepted for both playlist-write methods, grants that same edit-and-delete level of access. That is the review lane a playlist tool sits in once it moves past read-only. Google states the sensitive-scope verification process can take up to 10 days to complete, and that estimate does not include the separate brand verification most apps also need first. We've covered the fuller version of this tier system, including where Google's own pages disagree with each other, in Google OAuth Sensitive vs Restricted Scopes.

Until that review completes, the project is not stuck — it can stay in Testing, where verification is not required. But Testing comes with its own limits: a capped list of test users you manage by hand, and a refresh-token lifetime that is cut short for any scope beyond basic identity. A playlist-builder tool almost always needs more than identity scopes, so that exception does not apply to it.

Where playlist-builder projects actually stall

  • Reading playlists works, so the OAuth requirement gets discovered lateplaylists.list with the mine parameter and public playlist reads can go a long way on a simpler auth setup before anyone tries the first insert call and gets an authorization error instead of a data error.
  • The position parameter is set on a playlist that is not manually sortedplaylistItems.insert returns manualSortRequired the moment a position value is sent to a playlist still using YouTube's default ordering. The playlist's Ordering setting has to be switched to Manual first — there is no way to set position and have YouTube switch the mode for you.
  • The tool tries to add a video to a channel's own uploads playlistGoogle's error table names this specifically: playlistOperationUnsupported blocks inserting videos into a channel's auto-generated uploads playlist through this endpoint, even though that playlist is readable and returned by playlists.list like any other.
  • Playlist or item limits get hit with no published number to plan aroundmaxPlaylistExceeded and playlistContainsMaximumNumberOfVideos are both real, documented errors — but neither reference page publishes the actual ceiling. Teams building bulk-import tools discover the limit by hitting it, not by reading a spec.
  • Quota gets spent on inserts before anyone budgets for readsEvery playlists.insert and playlistItems.insert call costs 50 units against the same 10,000-unit default daily pool that search.list and videos.list draw from. A modest onboarding flow that builds five playlists of twenty videos each spends 5,500 units on writes alone.
50quota units per playlists.insert call
50quota units per playlistItems.insert call
10,000default combined daily quota units
10 dayssensitive-scope verification, per Google's own estimate

Errors Google's own reference pages document

ErrorMethodWhat it means
playlistTitleRequiredplaylists.insertsnippet.title was left empty — the only property playlists.insert actually requires.
maxPlaylistExceededplaylists.insertChannel already holds the maximum number of playlists Google allows — no published number.
playlistForbiddenplaylists.insertRequest is not properly authorized — commonly a scope or token problem, not a data problem.
resourceIdRequired / playlistIdRequiredplaylistItems.insertsnippet.playlistId or snippet.resourceId was left out of the request body.
manualSortRequiredplaylistItems.insertA position value was sent to a playlist that is not set to manual ordering.
playlistContainsMaximumNumberOfVideosplaylistItems.insertTarget playlist already holds the maximum items Google allows — no published number.
playlistOperationUnsupportedplaylistItems.insertAttempted insert into a playlist type the API does not accept writes for, such as a channel's uploads playlist.
videoAlreadyInAnotherSeriesPlaylistplaylistItems.insertThe video is already committed to a different series playlist and cannot be added to this one.

What Google does not publish for this API

  • No numeric ceiling for maxPlaylistExceeded or playlistContainsMaximumNumberOfVideos — both errors are documented, neither limit is.
  • No scope-by-scope sensitivity table naming youtube.force-ssl directly — only the general sensitive-scope framework and worked examples like deleting a YouTube video, which the same scope's edit-and-delete access falls under.
  • No batch or bulk variant of playlistItems.insert — every video added is a separate authorized call at its own quota cost.
  • No fast-track review path for playlist-only use cases — the review lane is the same one every other sensitive-scope YouTube integration goes through.

None of this is a reason to avoid the Playlists API — it is the reason a just-wire-up-the-SDK estimate for a playlist feature is usually wrong. The scope decision, the quota budget across reads and writes, and the sensitive-scope submission all have to be planned before the first insert call ships to real users, not discovered after test users run out. We've written about the OAuth-vs-API-key line in general in YouTube API Key vs OAuth 2.0, and about what happens once quota needs grow past the default in YouTube Data API Quota Increase. Scoping the exact authorization path, quota budget, and review submission for a specific playlist feature is the part we handle for clients — and deliberately the part this article does not hand over as a step-by-step build.

3 scopes onlyyoutubepartner, youtube, or youtube.force-ssl — no API-key path
50 + 50 unitsMinimum cost to create one playlist and add one video
Sensitive-scope laneSame review track as any YouTube edit/delete scope