Videos: insert

All videos uploaded via the videos.insert endpoint from unverified API projects created after 28 July 2020 will be restricted to private viewing mode. To lift this restriction, each API project must undergo an audit to verify compliance with the Terms of Service . Please see the API Revision History for more details.

Uploads a video to YouTube and optionally sets the video's metadata.

This method supports media upload. Uploaded files must conform to these constraints:

  • Maximum file size:256GB
  • Accepted Media MIME types: video/* , application/octet-stream

Quota impact: A call to this method has a quota cost of 1600 units.

Common use cases

Request

HTTP request

POST https://www.googleapis.com/upload/youtube/v3/videos

Authorization

This request requires authorization with at least one of the following scopes ( read more about authentication and authorization ).

Scope
https://www.googleapis.com/auth/youtube.upload
https://www.googleapis.com/auth/youtube
https://www.googleapis.com/auth/youtubepartner
https://www.googleapis.com/auth/youtube.force-ssl

Parameters

The following table lists the parameters that this query supports. All of the parameters listed are query parameters.

Parameters
Required parameters
part
string
The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.

Note that not all parts contain properties that can be set when inserting or updating a video. For example, the statistics object encapsulates statistics that YouTube calculates for a video and does not contain values that you can set or modify. If the parameter value specifies a part that does not contain mutable values, that part will still be included in the API response.

The following list contains the part names that you can include in the parameter value:
  • contentDetails
  • fileDetails
  • id
  • liveStreamingDetails
  • localizations
  • paidProductPlacementDetails
  • player
  • processingDetails
  • recordingDetails
  • snippet
  • statistics
  • status
  • suggestions
  • topicDetails
Optional parameters
notifySubscribers
boolean
The notifySubscribers parameter indicates whether YouTube should send a notification about the new video to users who subscribe to the video's channel. A parameter value of True indicates that subscribers will be notified of newly uploaded videos. However, a channel owner who is uploading many videos might prefer to set the value to False to avoid sending a notification about each new video to the channel's subscribers. The default value is True .
onBehalfOfContentOwner
string
This parameter can only be used in a properly authorized request . Note:This parameter is intended exclusively for YouTube content partners.

The onBehalfOfContentOwner parameter indicates that the request's authorization credentials identify a YouTube CMS user who is acting on behalf of the content owner specified in the parameter value. This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and get access to all their video and channel data, without having to provide authentication credentials for each individual channel. The CMS account that the user authenticates with must be linked to the specified YouTube content owner.
onBehalfOfContentOwnerChannel
string
This parameter can only be used in a properly authorized request . This parameter can only be used in a properly authorized request . Note:This parameter is intended exclusively for YouTube content partners.

The onBehalfOfContentOwnerChannel parameter specifies the YouTube channel ID of the channel to which a video is being added. This parameter is required when a request specifies a value for the onBehalfOfContentOwner parameter, and it can only be used in conjunction with that parameter. In addition, the request must be authorized using a CMS account that is linked to the content owner that the onBehalfOfContentOwner parameter specifies. Finally, the channel that the onBehalfOfContentOwnerChannel parameter value specifies must be linked to the content owner that the onBehalfOfContentOwner parameter specifies.

This parameter is intended for YouTube content partners that own and manage many different YouTube channels. It allows content owners to authenticate once and perform actions on behalf of the channel specified in the parameter value, without having to provide authentication credentials for each separate channel.

Request body

Provide a video resource in the request body. For that resource:

  • You can set values for these properties:

    • snippet.title
    • snippet.description
    • snippet.tags[]
    • snippet.categoryId
    • snippet.defaultLanguage
    • localizations.(key)
    • localizations.(key).title
    • localizations.(key).description
    • status.embeddable
    • status.license
    • status.privacyStatus
    • status.publicStatsViewable
    • status.publishAt
    • status.selfDeclaredMadeForKids
    • status.containsSyntheticMedia
    • recordingDetails.recordingDate

Response

If successful, this method returns a video resource in the response body.

Examples

Note:The following code samples may not represent all supported programming languages. See the client libraries documentation for a list of supported languages.

Go

This code sample calls the API's videos.insert method to upload a video to the channel associated with the request.

This example uses the Go client library .

 package 
  
 main 
 import 
  
 ( 
  
 "flag" 
  
 "fmt" 
  
 "log" 
  
 "os" 
  
 "strings" 
  
 "google.golang.org/api/youtube/v3" 
 ) 
 var 
  
 ( 
  
 filename 
  
 = 
  
 flag 
 . 
 String 
 ( 
 "filename" 
 , 
  
 "" 
 , 
  
 "Name of video file to upload" 
 ) 
  
 title 
  
 = 
  
 flag 
 . 
 String 
 ( 
 "title" 
 , 
  
 "Test Title" 
 , 
  
 "Video title" 
 ) 
  
 description 
  
 = 
  
 flag 
 . 
 String 
 ( 
 "description" 
 , 
  
 "Test Description" 
 , 
  
 "Video description" 
 ) 
  
 category 
  
 = 
  
 flag 
 . 
 String 
 ( 
 "category" 
 , 
  
 "22" 
 , 
  
 "Video category" 
 ) 
  
 keywords 
  
 = 
  
 flag 
 . 
 String 
 ( 
 "keywords" 
 , 
  
 "" 
 , 
  
 "Comma separated list of video keywords" 
 ) 
  
 privacy 
  
 = 
  
 flag 
 . 
 String 
 ( 
 "privacy" 
 , 
  
 "unlisted" 
 , 
  
 "Video privacy status" 
 ) 
 ) 
 func 
  
 main 
 () 
  
 { 
  
 flag 
 . 
 Parse 
 () 
  
 if 
  
 * 
 filename 
  
 == 
  
 "" 
  
 { 
  
 log 
 . 
 Fatalf 
 ( 
 "You must provide a filename of a video file to upload" 
 ) 
  
 } 
  
 client 
  
 := 
  
 getClient 
 ( 
 youtube 
 . 
 YoutubeUploadScope 
 ) 
  
 service 
 , 
  
 err 
  
 := 
  
 youtube 
 . 
 New 
 ( 
 client 
 ) 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 log 
 . 
 Fatalf 
 ( 
 "Error creating YouTube client: %v" 
 , 
  
 err 
 ) 
  
 } 
  
 upload 
  
 := 
  
& youtube 
 . 
 Video 
 { 
  
 Snippet 
 : 
  
& youtube 
 . 
 VideoSnippet 
 { 
  
 Title 
 : 
  
 * 
 title 
 , 
  
 Description 
 : 
  
 * 
 description 
 , 
  
 CategoryId 
 : 
  
 * 
 category 
 , 
  
 }, 
  
 Status 
 : 
  
& youtube 
 . 
 VideoStatus 
 { 
 PrivacyStatus 
 : 
  
 * 
 privacy 
 }, 
  
 } 
  
 // The API returns a 400 Bad Request response if tags is an empty string. 
  
 if 
  
 strings 
 . 
 Trim 
 ( 
 * 
 keywords 
 , 
  
 "" 
 ) 
  
 != 
  
 "" 
  
 { 
  
 upload 
 . 
 Snippet 
 . 
 Tags 
  
 = 
  
 strings 
 . 
 Split 
 ( 
 * 
 keywords 
 , 
  
 "," 
 ) 
  
 } 
  
 call 
  
 := 
  
 service 
 . 
 Videos 
 . 
 Insert 
 ( 
 "snippet,status" 
 , 
  
 upload 
 ) 
  
 file 
 , 
  
 err 
  
 := 
  
 os 
 . 
 Open 
 ( 
 * 
 filename 
 ) 
  
 defer 
  
 file 
 . 
 Close 
 () 
  
 if 
  
 err 
  
 != 
  
 nil 
  
 { 
  
 log 
 . 
 Fatalf 
 ( 
 "Error opening %v: %v" 
 , 
  
 * 
 filename 
 , 
  
 err 
 ) 
  
 } 
  
 response 
 , 
  
 err 
  
 := 
  
 call 
 . 
 Media 
 ( 
 file 
 ). 
 Do 
 () 
  
 handleError 
 ( 
 err 
 , 
  
 "" 
 ) 
  
 fmt 
 . 
 Printf 
 ( 
 "Upload successful! Video ID: %v\n" 
 , 
  
 response 
 . 
 Id 
 ) 
 } 
  

.NET

The following code sample calls the API's videos.insert method to upload a video to the channel associated with the request.

This example uses the .NET client library .

 using 
  
 System 
 ; 
 using 
  
 System 
 . 
 IO 
 ; 
 using 
  
 System 
 . 
 Reflection 
 ; 
 using 
  
 System 
 . 
 Threading 
 ; 
 using 
  
 System 
 . 
 Threading 
 . 
 Tasks 
 ; 
 using 
  
 Google 
 . 
 Apis 
 . 
 Auth 
 . 
 OAuth2 
 ; 
 using 
  
 Google 
 . 
 Apis 
 . 
 Services 
 ; 
 using 
  
 Google 
 . 
 Apis 
 . 
 Upload 
 ; 
 using 
  
 Google 
 . 
 Apis 
 . 
 Util 
 . 
 Store 
 ; 
 using 
  
 Google 
 . 
 Apis 
 . 
 YouTube 
 . 
 v3 
 ; 
 using 
  
 Google 
 . 
 Apis 
 . 
 YouTube 
 . 
 v3 
 . 
 Data 
 ; 
 namespace 
  
 Google 
 . 
 Apis 
 . 
 YouTube 
 . 
 Samples 
 { 
  
 /// <summary> 
  
 /// YouTube Data API v3 sample: upload a video. 
  
 /// Relies on the Google APIs Client Library for .NET, v1.7.0 or higher. 
  
 /// See https://developers.google.com/api-client-library/dotnet/get_started 
  
 /// </summary> 
  
 internal 
  
 class 
  
 UploadVideo 
  
 { 
  
 [ 
 STAThread 
 ] 
  
 static 
  
 void 
  
 Main 
 ( 
 string 
 [] 
  
 args 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 "YouTube Data API: Upload Video" 
 ); 
  
 Console 
 . 
 WriteLine 
 ( 
 "==============================" 
 ); 
  
 try 
  
 { 
  
 new 
  
 UploadVideo 
 (). 
 Run 
 (). 
 Wait 
 (); 
  
 } 
  
 catch 
  
 ( 
 AggregateException 
  
 ex 
 ) 
  
 { 
  
 foreach 
  
 ( 
 var 
  
 e 
  
 in 
  
 ex 
 . 
 InnerExceptions 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 "Error: " 
  
 + 
  
 e 
 . 
 Message 
 ); 
  
 } 
  
 } 
  
 Console 
 . 
 WriteLine 
 ( 
 "Press any key to continue..." 
 ); 
  
 Console 
 . 
 ReadKey 
 (); 
  
 } 
  
 private 
  
 async 
  
 Task 
  
 Run 
 () 
  
 { 
  
 UserCredential 
  
 credential 
 ; 
  
 using 
  
 ( 
 var 
  
 stream 
  
 = 
  
 new 
  
 FileStream 
 ( 
 "client_secrets.json" 
 , 
  
 FileMode 
 . 
 Open 
 , 
  
 FileAccess 
 . 
 Read 
 )) 
  
 { 
  
 credential 
  
 = 
  
 await 
  
 GoogleWebAuthorizationBroker 
 . 
 AuthorizeAsync 
 ( 
  
 GoogleClientSecrets 
 . 
 Load 
 ( 
 stream 
 ). 
 Secrets 
 , 
  
 // This OAuth 2.0 access scope allows an application to upload files to the 
  
 // authenticated user's YouTube channel, but doesn't allow other types of access. 
  
 new 
 [] 
  
 { 
  
 YouTubeService 
 . 
 Scope 
 . 
 YoutubeUpload 
  
 }, 
  
 "user" 
 , 
  
 CancellationToken 
 . 
 None 
  
 ); 
  
 } 
  
 var 
  
 youtubeService 
  
 = 
  
 new 
  
 YouTubeService 
 ( 
 new 
  
 BaseClientService 
 . 
 Initializer 
 () 
  
 { 
  
 HttpClientInitializer 
  
 = 
  
 credential 
 , 
  
 ApplicationName 
  
 = 
  
 Assembly 
 . 
 GetExecutingAssembly 
 (). 
 GetName 
 (). 
 Name 
  
 }); 
  
 var 
  
 video 
  
 = 
  
 new 
  
 Video 
 (); 
  
 video 
 . 
 Snippet 
  
 = 
  
 new 
  
 VideoSnippet 
 (); 
  
 video 
 . 
 Snippet 
 . 
 Title 
  
 = 
  
 "Default Video Title" 
 ; 
  
 video 
 . 
 Snippet 
 . 
 Description 
  
 = 
  
 "Default Video Description" 
 ; 
  
 video 
 . 
 Snippet 
 . 
 Tags 
  
 = 
  
 new 
  
 string 
 [] 
  
 { 
  
 "tag1" 
 , 
  
 "tag2" 
  
 }; 
  
 video 
 . 
 Snippet 
 . 
 CategoryId 
  
 = 
  
 "22" 
 ; 
  
 // See https://developers.google.com/youtube/v3/docs/videoCategories/list 
  
 video 
 . 
 Status 
  
 = 
  
 new 
  
 VideoStatus 
 (); 
  
 video 
 . 
 Status 
 . 
 PrivacyStatus 
  
 = 
  
 "unlisted" 
 ; 
  
 // or "private" or "public" 
  
 var 
  
 filePath 
  
 = 
  
 @"REPLACE_ME.mp4" 
 ; 
  
 // Replace with path to actual movie file. 
  
 using 
  
 ( 
 var 
  
 fileStream 
  
 = 
  
 new 
  
 FileStream 
 ( 
 filePath 
 , 
  
 FileMode 
 . 
 Open 
 )) 
  
 { 
  
 var 
  
 videosInsertRequest 
  
 = 
  
 youtubeService 
 . 
 Videos 
 . 
 Insert 
 ( 
 video 
 , 
  
 "snippet,status" 
 , 
  
 fileStream 
 , 
  
 "video/*" 
 ); 
  
 videosInsertRequest 
 . 
 ProgressChanged 
  
 += 
  
 videosInsertRequest_ProgressChanged 
 ; 
  
 videosInsertRequest 
 . 
 ResponseReceived 
  
 += 
  
 videosInsertRequest_ResponseReceived 
 ; 
  
 await 
  
 videosInsertRequest 
 . 
 UploadAsync 
 (); 
  
 } 
  
 } 
  
 void 
  
 videosInsertRequest_ProgressChanged 
 ( 
 Google 
 . 
 Apis 
 . 
 Upload 
 . 
 IUploadProgress 
  
 progress 
 ) 
  
 { 
  
 switch 
  
 ( 
 progress 
 . 
 Status 
 ) 
  
 { 
  
 case 
  
 UploadStatus 
 . 
 Uploading 
 : 
  
 Console 
 . 
 WriteLine 
 ( 
 "{0} bytes sent." 
 , 
  
 progress 
 . 
 BytesSent 
 ); 
  
 break 
 ; 
  
 case 
  
 UploadStatus 
 . 
 Failed 
 : 
  
 Console 
 . 
 WriteLine 
 ( 
 "An error prevented the upload from completing. 
 \n 
 {0}" 
 , 
  
 progress 
 . 
 Exception 
 ); 
  
 break 
 ; 
  
 } 
  
 } 
  
 void 
  
 videosInsertRequest_ResponseReceived 
 ( 
 Video 
  
 video 
 ) 
  
 { 
  
 Console 
 . 
 WriteLine 
 ( 
 "Video id '{0}' was successfully uploaded." 
 , 
  
 video 
 . 
 Id 
 ); 
  
 } 
  
 } 
 } 
  

Ruby

This sample calls the API's videos.insert method to upload a video to the channel associated with the request.

This example uses the Ruby client library .

 #!/usr/bin/ruby 
 require 
  
 'rubygems' 
 gem 
  
 'google-api-client' 
 , 
  
 '>0.7' 
 require 
  
 'google/api_client' 
 require 
  
 'google/api_client/client_secrets' 
 require 
  
 'google/api_client/auth/file_storage' 
 require 
  
 'google/api_client/auth/installed_app' 
 require 
  
 'trollop' 
 # A limited OAuth 2 access scope that allows for uploading files, but not other 
 # types of account access. 
 YOUTUBE_UPLOAD_SCOPE 
  
 = 
  
 'https://www.googleapis.com/auth/youtube.upload' 
 YOUTUBE_API_SERVICE_NAME 
  
 = 
  
 'youtube' 
 YOUTUBE_API_VERSION 
  
 = 
  
 'v3' 
 def 
  
 get_authenticated_service 
  
 client 
  
 = 
  
 Google 
 :: 
 APIClient 
 . 
 new 
 ( 
  
 :application_name 
  
 = 
>  
 $PROGRAM_NAME 
 , 
  
 :application_version 
  
 = 
>  
 '1.0.0' 
  
 ) 
  
 youtube 
  
 = 
  
 client 
 . 
 discovered_api 
 ( 
 YOUTUBE_API_SERVICE_NAME 
 , 
  
 YOUTUBE_API_VERSION 
 ) 
  
 file_storage 
  
 = 
  
 Google 
 :: 
 APIClient 
 :: 
 FileStorage 
 . 
 new 
 ( 
 " 
 #{ 
 $PROGRAM_NAME 
 } 
 -oauth2.json" 
 ) 
  
 if 
  
 file_storage 
 . 
 authorization 
 . 
 nil? 
  
 client_secrets 
  
 = 
  
 Google 
 :: 
 APIClient 
 :: 
 ClientSecrets 
 . 
 load 
  
 flow 
  
 = 
  
 Google 
 :: 
 APIClient 
 :: 
 InstalledAppFlow 
 . 
 new 
 ( 
  
 :client_id 
  
 = 
>  
 client_secrets 
 . 
 client_id 
 , 
  
 :client_secret 
  
 = 
>  
 client_secrets 
 . 
 client_secret 
 , 
  
 :scope 
  
 = 
>  
 [ 
 YOUTUBE_UPLOAD_SCOPE 
 ] 
  
 ) 
  
 client 
 . 
 authorization 
  
 = 
  
 flow 
 . 
 authorize 
 ( 
 file_storage 
 ) 
  
 else 
  
 client 
 . 
 authorization 
  
 = 
  
 file_storage 
 . 
 authorization 
  
 end 
  
 return 
  
 client 
 , 
  
 youtube 
 end 
 def 
  
 main 
  
 opts 
  
 = 
  
 Trollop 
 :: 
 options 
  
 do 
  
 opt 
  
 :file 
 , 
  
 'Video file to upload' 
 , 
  
 :type 
  
 = 
>  
 String 
  
 opt 
  
 :title 
 , 
  
 'Video title' 
 , 
  
 :default 
  
 = 
>  
 'Test Title' 
 , 
  
 :type 
  
 = 
>  
 String 
  
 opt 
  
 :description 
 , 
  
 'Video description' 
 , 
  
 :default 
  
 = 
>  
 'Test Description' 
 , 
  
 :type 
  
 = 
>  
 String 
  
 opt 
  
 :category_id 
 , 
  
 'Numeric video category. See https://developers.google.com/youtube/v3/docs/videoCategories/list' 
 , 
  
 :default 
  
 = 
>  
 22 
 , 
  
 :type 
  
 = 
>  
 :int 
  
 opt 
  
 :keywords 
 , 
  
 'Video keywords, comma-separated' 
 , 
  
 :default 
  
 = 
>  
 '' 
 , 
  
 :type 
  
 = 
>  
 String 
  
 opt 
  
 :privacy_status 
 , 
  
 'Video privacy status: public, private, or unlisted' 
 , 
  
 :default 
  
 = 
>  
 'public' 
 , 
  
 :type 
  
 = 
>  
 String 
  
 end 
  
 if 
  
 opts 
 [ 
 :file 
 ]. 
 nil? 
  
 or 
  
 not 
  
 File 
 . 
 file? 
 ( 
 opts 
 [ 
 :file 
 ] 
 ) 
  
 Trollop 
 :: 
 die 
  
 :file 
 , 
  
 'does not exist' 
  
 end 
  
 client 
 , 
  
 youtube 
  
 = 
  
 get_authenticated_service 
  
 begin 
  
 body 
  
 = 
  
 { 
  
 :snippet 
  
 = 
>  
 { 
  
 :title 
  
 = 
>  
 opts 
 [ 
 :title 
 ] 
 , 
  
 :description 
  
 = 
>  
 opts 
 [ 
 :description 
 ] 
 , 
  
 :tags 
  
 = 
>  
 opts 
 [ 
 :keywords 
 ]. 
 split 
 ( 
 ',' 
 ), 
  
 :categoryId 
  
 = 
>  
 opts 
 [ 
 :category_id 
 ] 
 , 
  
 }, 
  
 :status 
  
 = 
>  
 { 
  
 :privacyStatus 
  
 = 
>  
 opts 
 [ 
 :privacy_status 
 ] 
  
 } 
  
 } 
  
 videos_insert_response 
  
 = 
  
 client 
 . 
 execute! 
 ( 
  
 :api_method 
  
 = 
>  
 youtube 
 . 
 videos 
 . 
 insert 
 , 
  
 :body_object 
  
 = 
>  
 body 
 , 
  
 :media 
  
 = 
>  
 Google 
 :: 
 APIClient 
 :: 
 UploadIO 
 . 
 new 
 ( 
 opts 
 [ 
 :file 
 ] 
 , 
  
 'video/*' 
 ), 
  
 :parameters 
  
 = 
>  
 { 
  
 :uploadType 
  
 = 
>  
 'resumable' 
 , 
  
 :part 
  
 = 
>  
 body 
 . 
 keys 
 . 
 join 
 ( 
 ',' 
 ) 
  
 } 
  
 ) 
  
 videos_insert_response 
 . 
 resumable_upload 
 . 
 send_all 
 ( 
 client 
 ) 
  
 puts 
  
 "Video id ' 
 #{ 
 videos_insert_response 
 . 
 data 
 . 
 id 
 } 
 ' was successfully uploaded." 
  
 rescue 
  
 Google 
 :: 
 APIClient 
 :: 
 TransmissionError 
  
 = 
>  
 e 
  
 puts 
  
 e 
 . 
 result 
 . 
 body 
  
 end 
 end 
 main 
  

Errors

The following table identifies error messages that the API could return in response to a call to this method. Please see the error message documentation for more detail.

Error type Error detail Description
badRequest (400)
defaultLanguageNotSet The request is trying to add localized video details without specifying the default language of the video details.
badRequest (400)
invalidCategoryId The snippet.categoryId property specifies an invalid category ID. Use the videoCategories.list method to retrieve supported categories.
badRequest (400)
invalidDescription The request metadata specifies an invalid video description.
badRequest (400)
invalidFilename The video filename specified in the Slug header is invalid.
badRequest (400)
invalidPublishAt The request metadata specifies an invalid scheduled publishing time.
badRequest (400)
invalidRecordingDetails The recordingDetails object in the request metadata specifies invalid recording details.
badRequest (400)
invalidTags The request metadata specifies invalid video keywords.
badRequest (400)
invalidTitle The request metadata specifies an invalid or empty video title.
badRequest (400)
invalidVideoGameRating The request metadata specifies an invalid video game rating.
badRequest (400)
mediaBodyRequired The request does not include the video content.
badRequest (400)
uploadLimitExceeded The user has exceeded the number of videos they may upload.
forbidden (403)
forbidden
forbidden (403)
forbiddenLicenseSetting The request attempts to set an invalid license for the video.
forbidden (403)
forbiddenPrivacySetting The request attempts to set an invalid privacy setting for the video.

Try it!

Use the APIs Explorer to call this API and see the API request and response.

Design a Mobile Site
View Site in Mobile | Classic
Share by: