YouTube

Videos: update

Updates a video's metadata. Try it now or see an example.

Request

HTTP request

PUT https://www.googleapis.com/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/youtubepartner
https://www.googleapis.com/auth/youtube

Parameters

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

Parameter name Value Description
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.

The part names that you can include in the parameter value are snippet, contentDetails, fileDetails, liveStreamingDetails, player, processingDetails, recordingDetails, statistics, status, suggestions, and topicDetails.

Note that this method will override the existing values for all of the mutable properties that are contained in any parts that the parameter value specifies. For example, a video's privacy setting is contained in the status part. As such, if your request is updating a private video, and the request's part parameter value includes the status part, the video's privacy setting will be updated to whatever value the request body specifies. If the request body does not specify a value, the existing privacy setting will be removed and the video will revert to the default privacy setting.

In addition, not all of those parts contain properties that can be set when setting or updating a video's metadata. 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.
Optional parameters
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 actual CMS account that the user authenticates with must be linked to the specified YouTube content owner.

Request body

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

  • You must specify a value for these properties:

    • id

  • You can set values for these properties:

    • snippet.title
    • snippet.description
    • snippet.tags[]
    • snippet.categoryId
    • status.privacyStatus
    • status.embeddable
    • status.license
    • status.publicStatsViewable
    • status.publishAt
    • recordingDetails.locationDescription
    • recordingDetails.location.latitude
    • recordingDetails.location.longitude
    • recordingDetails.recordingDate

    If you are submitting an update request, and your request does not specify a value for a property that already has a value, the property's existing value will be deleted.

Response

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

Examples

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

Apps Script

This sample finds the active user's uploads, then updates the most recent upload's description by appending a string.
/**
 * This sample finds the active user's uploads, then updates the most recent
 * upload's description by appending a string.
 */
function updateVideo() {
  // 1. Fetch all the channels owned by active user
  var myChannels = YouTube.Channels.list('contentDetails', {mine: true});
  // 2. Iterate through the channels and get the uploads playlist ID
  for (var i = 0; i < myChannels.items.length; i++) {
    var item = myChannels.items[i];
    var uploadsPlaylistId = item.contentDetails.relatedPlaylists.uploads;

    var playlistResponse = YouTube.PlaylistItems.list('snippet', {
      playlistId: uploadsPlaylistId,
      maxResults: 1
    });

    // Get the videoID of the first video in the list
    var video = playlistResponse.items[0];
    var originalDescription = video.snippet.description;
    var updatedDescription = originalDescription + ' Description updated via Google Apps Script';

    video.snippet.description = updatedDescription;

    var resource = {
      snippet: {
        title: video.snippet.title,
        description: updatedDescription,
        categoryId: '22'
      },
      id: video.snippet.resourceId.videoId
    };
    YouTube.Videos.update(resource, 'id,snippet');
  }
}

Java

This example uses the Java client library.

/*
 * Copyright (c) 2013 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.api.services.samples.youtube.cmdline.data;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.services.samples.youtube.cmdline.Auth;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Video;
import com.google.api.services.youtube.model.VideoListResponse;
import com.google.api.services.youtube.model.VideoSnippet;
import com.google.common.collect.Lists;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * Update a video by adding a keyword tag to its metadata. The demo uses the
 * YouTube Data API (v3) and OAuth 2.0 for authorization.
 *
 * @author Ibrahim Ulukaya
 */
public class UpdateVideo {

    /**
     * Define a global instance of a Youtube object, which will be used
     * to make YouTube Data API requests.
     */
    private static YouTube youtube;

    /**
     * Add a keyword tag to a video that the user specifies. Use OAuth 2.0 to
     * authorize the API request.
     *
     * @param args command line args (not used).
     */
    public static void main(String[] args) {

        // This OAuth 2.0 access scope allows for full read/write access to the
        // authenticated user's account.
        List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube");

        try {
            // Authorize the request.
            Credential credential = Auth.authorize(scopes, "updatevideo");

            // This object is used to make YouTube Data API requests.
            youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential)
                    .setApplicationName("youtube-cmdline-updatevideo-sample").build();

            // Prompt the user to enter the video ID of the video being updated.
            String videoId = getVideoIdFromUser();
            System.out.println("You chose " + videoId + " to update.");

            // Prompt the user to enter a keyword tag to add to the video.
            String tag = getTagFromUser();
            System.out.println("You chose " + tag + " as a tag.");

            // Call the YouTube Data API's youtube.videos.list method to
            // retrieve the resource that represents the specified video.
            YouTube.Videos.List listVideosRequest = youtube.videos().list("snippet").setId(videoId);
            VideoListResponse listResponse = listVideosRequest.execute();

            // Since the API request specified a unique video ID, the API
            // response should return exactly one video. If the response does
            // not contain a video, then the specified video ID was not found.
            List<Video> videoList = listResponse.getItems();
            if (videoList.isEmpty()) {
                System.out.println("Can't find a video with ID: " + videoId);
                return;
            }

            // Extract the snippet from the video resource.
            Video video = videoList.get(0);
            VideoSnippet snippet = video.getSnippet();

            // Preserve any tags already associated with the video. If the
            // video does not have any tags, create a new array. Append the
            // provided tag to the list of tags associated with the video.
            List<String> tags = snippet.getTags();
            if (tags == null) {
                tags = new ArrayList<String>(1);
                snippet.setTags(tags);
            }
            tags.add(tag);

            // Update the video resource by calling the videos.update() method.
            YouTube.Videos.Update updateVideosRequest = youtube.videos().update("snippet", video);
            Video videoResponse = updateVideosRequest.execute();

            // Print information from the updated resource.
            System.out.println("\n================== Returned Video ==================\n");
            System.out.println("  - Title: " + videoResponse.getSnippet().getTitle());
            System.out.println("  - Tags: " + videoResponse.getSnippet().getTags());

        } catch (GoogleJsonResponseException e) {
            System.err.println("GoogleJsonResponseException code: " + e.getDetails().getCode() + " : "
                    + e.getDetails().getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("IOException: " + e.getMessage());
            e.printStackTrace();
        } catch (Throwable t) {
            System.err.println("Throwable: " + t.getMessage());
            t.printStackTrace();
        }
    }

    /*
     * Prompt the user to enter a keyword tag.
     */
    private static String getTagFromUser() throws IOException {

        String keyword = "";

        System.out.print("Please enter a tag for your video: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        keyword = bReader.readLine();

        if (keyword.length() < 1) {
            // If the user doesn't enter a tag, use the default value "New Tag."
            keyword = "New Tag";
        }
        return keyword;
    }

    /*
     * Prompt the user to enter a video ID.
     */
    private static String getVideoIdFromUser() throws IOException {

        String videoId = "";

        System.out.print("Please enter a video Id to update: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        videoId = bReader.readLine();

        if (videoId.length() < 1) {
            // Exit if the user doesn't provide a value.
            System.out.print("Video Id can't be empty!");
            System.exit(1);
        }

        return videoId;
    }

}

PHP

This code sample demonstrates how to add tags into an existing video.

The code sample below calls the API's youtube.videos.list method with id parameter set to videoId to get the video object. Using this video object, the sample gets the list of tags and appends new tags at the end of this list. Finally, the code calls youtube.videos.update method with updated video object to persist these changes on YouTube.

This example uses the PHP client library.

<?php

/**
 * This sample adds new tags to a YouTube video by:
 *
 * 1. Retrieving the video resource by calling the "youtube.videos.list" method
 *    and setting the "id" parameter
 * 2. Appending new tags to the video resource's snippet.tags[] list
 * 3. Updating the video resource by calling the youtube.videos.update method.
 *
 * @author Ibrahim Ulukaya
*/

// Call set_include_path() as needed to point to your client library.
require_once 'Google/Client.php';
require_once 'Google/Service/YouTube.php';
session_start();

/*
 * You can acquire an OAuth 2.0 client ID and client secret from the
 * Google Developers Console <https://console.developers.google.com/>
 * For more information about using OAuth 2.0 to access Google APIs, please see:
 * <https://developers.google.com/youtube/v3/guides/authentication>
 * Please ensure that you have enabled the YouTube Data API for your project.
 */
$OAUTH2_CLIENT_ID = 'REPLACE_ME';
$OAUTH2_CLIENT_SECRET = 'REPLACE_ME';

$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes('https://www.googleapis.com/auth/youtube');
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'],
    FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);

// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);

if (isset($_GET['code'])) {
  if (strval($_SESSION['state']) !== strval($_GET['state'])) {
    die('The session state did not match.');
  }

  $client->authenticate($_GET['code']);
  $_SESSION['token'] = $client->getAccessToken();
  header('Location: ' . $redirect);
}

if (isset($_SESSION['token'])) {
  $client->setAccessToken($_SESSION['token']);
}

// Check to ensure that the access token was successfully acquired.
if ($client->getAccessToken()) {
  try{

    // REPLACE this value with the video ID of the video being updated.
    $videoId = "VIDEO_ID";

    // Call the API's videos.list method to retrieve the video resource.
    $listResponse = $youtube->videos->listVideos("snippet",
        array('id' => $videoId));

    // If $listResponse is empty, the specified video was not found.
    if (empty($listResponse)) {
      $htmlBody .= sprintf('<h3>Can\'t find a video with video id: %s</h3>', $videoId);
    } else {
      // Since the request specified a video ID, the response only
      // contains one video resource.
      $video = $listResponse[0];
      $videoSnippet = $video['snippet'];
      $tags = $videoSnippet['tags'];

      // Preserve any tags already associated with the video. If the video does
      // not have any tags, create a new list. Replace the values "tag1" and
      // "tag2" with the new tags you want to associate with the video.
      if (is_null($tags)) {
        $tags = array("tag1", "tag2");
      } else {
        array_push($tags, "tag1", "tag2");
      }

      // Set the tags array for the video snippet
      $videoSnippet['tags'] = $tags;

      // Update the video resource by calling the videos.update() method.
      $updateResponse = $youtube->videos->update("snippet", $video);

      $responseTags = $updateResponse['snippet']['tags'];


    $htmlBody .= "<h3>Video Updated</h3><ul>";
    $htmlBody .= sprintf('<li>Tags "%s" and "%s" added for video %s (%s) </li>',
        array_pop($responseTags), array_pop($responseTags),
        $videoId, $video['snippet']['title']);

    $htmlBody .= '</ul>';
  }
    } catch (Google_ServiceException $e) {
      $htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
          htmlspecialchars($e->getMessage()));
    } catch (Google_Exception $e) {
      $htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
          htmlspecialchars($e->getMessage()));
    }

    $_SESSION['token'] = $client->getAccessToken();
    } else {
      // If the user hasn't authorized the app, initiate the OAuth flow
      $state = mt_rand();
      $client->setState($state);
      $_SESSION['state'] = $state;

      $authUrl = $client->createAuthUrl();
      $htmlBody = <<<END
  <h3>Authorization Required</h3>
  <p>You need to <a href="$authUrl">authorize access</a> before proceeding.<p>
END;
    }
    ?>

    <!doctype html>
    <html>
    <head>
    <title>Video Updated</title>
    </head>
    <body>
      <?=$htmlBody?>
    </body>
    </html>

Python

The code sample below calls the API's videos.update method to update a video owned by the channel authorizing the request.

This example uses the Python client library.

#!/usr/bin/python

import httplib2
import os
import sys

from apiclient.discovery import build
from apiclient.errors import HttpError
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import argparser, run_flow


# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
# the OAuth 2.0 information for this application, including its client_id and
# client_secret. You can acquire an OAuth 2.0 client ID and client secret from
# the Google Developers Console at
# https://console.developers.google.com/.
# Please ensure that you have enabled the YouTube Data API for your project.
# For more information about using OAuth2 to access the YouTube Data API, see:
#   https://developers.google.com/youtube/v3/guides/authentication
# For more information about the client_secrets.json file format, see:
#   https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
CLIENT_SECRETS_FILE = "client_secrets.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account.
YOUTUBE_READ_WRITE_SCOPE = "https://www.googleapis.com/auth/youtube"
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"

# This variable defines a message to display if the CLIENT_SECRETS_FILE is
# missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0

To make this sample run you will need to populate the client_secrets.json file
found at:

   %s

with information from the Developers Console
https://console.developers.google.com/

For more information about the client_secrets.json file format, please visit:
https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
""" % os.path.abspath(os.path.join(os.path.dirname(__file__),
                                   CLIENT_SECRETS_FILE))

def get_authenticated_service(args):
  flow = flow_from_clientsecrets(CLIENT_SECRETS_FILE,
    scope=YOUTUBE_READ_WRITE_SCOPE,
    message=MISSING_CLIENT_SECRETS_MESSAGE)

  storage = Storage("%s-oauth2.json" % sys.argv[0])
  credentials = storage.get()

  if credentials is None or credentials.invalid:
    credentials = run_flow(flow, storage, args)

  return build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION,
    http=credentials.authorize(httplib2.Http()))

def update_video(youtube, options):
  # Call the API's videos.list method to retrieve the video resource.
  videos_list_response = youtube.videos().list(
    id=options.video_id,
    part='snippet'
  ).execute()

  # If the response does not contain an array of "items" then the video was
  # not found.
  if not videos_list_response["items"]:
    print "Video '%s' was not found." % options.video_id
    sys.exit(1)

  # Since the request specified a video ID, the response only contains one
  # video resource. This code extracts the snippet from that resource.
  videos_list_snippet = videos_list_response["items"][0]["snippet"]

  # Preserve any tags already associated with the video. If the video does
  # not have any tags, create a new array. Append the provided tag to the
  # list of tags associated with the video.
  if "tags" not in  videos_list_snippet:
    videos_list_snippet["tags"] = []
  videos_list_snippet["tags"].append(options.tag)

  # Update the video resource by calling the videos.update() method.
  videos_update_response = youtube.videos().update(
    part='snippet',
    body=dict(
      snippet=videos_list_snippet,
      id=options.video_id
    )).execute()

if __name__ == "__main__":
  argparser.add_argument("--video-id", help="ID of video to update.",
    required=True)
  argparser.add_argument("--tag", default="youtube",
    help="Additional tag to add to video.")
  args = argparser.parse_args()

  youtube = get_authenticated_service(args)
  try:
    update_video(youtube, args)
  except HttpError, e:
    print "An HTTP error %d occurred:\n%s" % (e.resp.status, e.content)
  else:
    print "Tag '%s' was added to video id '%s'." % (args.tag, args.video_id)

Errors

The table below 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) invalidRequest The request metadata is invalid.
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.
notFound (404) videoNotFound The video that you are trying to update cannot be found. Check the value of the id field in the request body to ensure that it is correct.

Try it!

Use the API Explorer to call this method on live data and see the API request and response.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.