Reduce quota from YouTube API when calling channel videos? - youtube-api

I've been using the YouTube Data API and I want to just call the API and for it to return a channel's latest video. Currently I have been doing this:
https://www.googleapis.com/youtube/v3/search?key=[key]&channelId=[channelId]&part=id&order=date&maxResults=1,
but that still uses many units.
Is there any way to get the data I need without using so many units?

For the first question of yours:
I want to just call the API and for it to return a channel's latest video.
the answer is positive. You'll have to proceed as follows:
Step 1: Obtain the ID of the uploads playlist corresponding to the channel of your interest:
For a given channel -- identified by its ID CHANNEL_ID --, invoke the Channels.list API endpoint, queried with its request parameter id set to CHANNEL_ID:
https://www.googleapis.com/youtube/v3/channels?part=contentDetails&fields=items/contentDetails/relatedPlaylists/uploads&id=CHANNEL_ID&key=....
The needed uploads playlist ID is to be found as the value of the property contentDetails.relatedPlaylists.uploads of the Channels resource JSON object returned by the endpoint.
Usually, a channel ID and its corresponding uploads playlist ID are related by s/^UC([0-9a-zA-Z_-]{22})$/UU\1/.
Note that above I used the fields request parameter for to get from the API only the info that's actually needed.
Also note that you'll have to invoke Channels.list as above only once, for to use the obtained uploads playlist ID as many times as you need.
Step 2: Obtain the latest uploaded video of the channel of your interest:
For that you'll need to rely on an undocumented behavior of the PlaylistItems.list API endpoint queried with its playlistId request parameter set to the ID you've obtained at step 1:
According to point 2 of this answer of mine:
For the uploads playlist of a channel, the items returned by PlaylistItems.list API endpoint are (have to be) ordered in reverse chronological order by contentDetails.videoPublishedAt.
Therefore, you'll have to invoke PlaylistItems.list on the following URL repeatedly in a loop (using pagination):
https://www.googleapis.com/youtube/v3/playlistItems?playlistId=UPLOADS_ID&part=snippet&fields=nextPageToken,items/snippet/resourceId&maxResults=50&pageToken=PAGE_TOKEN&key=...
Above, UPLOADS_ID is the ID of the uploads playlist obtained at step 1.
The request parameter pageToken=PAGE_TOKEN is needed if and only if you're not invoking PlaylistItems.list for the first time. When the endpoint is invoked the N-th time, with N >= 2, then PAGE_TOKEN would be the value of the property nextPageToken of the JSON response obtained from the previous endpoint call. If an endpoint call does not provide the property nextPageToken then the pagination loop terminates.
The pagination of the result sets of PlaylistItems.list is needed for the sake of correctness of you implementation: you'll have to ignore the snippet objects of the items array obtained from each endpoint call when the value of the property snippet.resourceId.kind is not equal with youtube#video.
For each snippet object obtained from the endpoint that has snippet.resourceId.kind equal to youtube#video, the property snippet.resourceId.videoId is set to the ID of an uploaded video belonging to the playlist identified by UPLOADS_ID.
Therefore, the first time you encounter a snippet object of this latter kind, you retain the respective video ID and break off the pagination loop (thus invoking PlaylistItems.list no more).
For what concerns your second question:
Is there any way to get the data I need without using so many units?
again, the answer is positive.
Taking into account the quota costs, executing the step 1 taken once and the step 2 taken N times amounts to a cost of 1 + N * 1 = N + 1 units. Moreover, if step 1 is not executed, then the cost would be N units. (You need not execute step 1 once you already know UPLOADS_ID from previous runs of step 1 + 2.)
Also note that your pagination loop will most likely terminate with N being 1; thus your API calls would entail most probably only 2 units of quota cost. When step 1 is not executed, the quota cost implied would most probably be only 1 unit.

the following cost 2 unit
baseurl = https://www.googleapis.com/youtube/v3
Get channel "Upload" ID
{baseurl}/channels?part=contentDetails&id={channel Id}&key={api key}
then use upload id for playlistItems
{baseurl}/v3/playlistItems?playlistId={upload id}&part=snippet&maxResults={max numbers}&key={api key}

Related

YouTube Playlist Item API publishedAt field clarification

I have tested YouTube's PlaylistItems.list API to fetch a channel's default playlist.
In the response payload, a video -- that was published on 2020-10-14T20:22:24Z -- is in the first object, and then the next video -- that was published on 2020-10-21T17:54:05Z -- is in the second object.
In this answer it is mentioned that:
The publishedAt getting returned from a Playlist query is the date the
video was added to the playlist, rather than the date the video was
published on YouTube
What might be the reason for my case?
Is there any specific sorting order maintained for this API?
The reason you see the ordering you've exemplified (though you did not mentioned your playlist ID such that others to verify your claim) is two fold.
1. A video's publication time may well be different than its upload time
First thing is the following: according to the official docs of the Video resource's publishedAt property (the emphasis below is mine):
snippet.publishedAt (datetime)
The date and time that the video was published. Note that this time might be different than the time that the video was uploaded. For example, if a video is uploaded as a private video and then made public at a later time, this property will specify the time that the video was made public.
There are a couple of special cases:
If a video is uploaded as a private video and the video metadata is retrieved by the channel owner, then the property value specifies the date and time that the video was uploaded.
If a video is uploaded as an unlisted video, the property value also specifies the date and time that the video was uploaded. In this case, anyone who knows the video's unique video ID can retrieve the video metadata.
The value is specified in ISO 8601 format.
Therefore, in cases, it may very well be that a given video has different upload time and time of publication.
Furthermore, the official docs of PlaylistItems resource says the following w.r.t. two related properties:
snippet.publishedAt (datetime)
The date and time that the item was added to the playlist. The value is specified in ISO 8601 format.
contentDetails.videoPublishedAt (datetime)
The date and time that the video was published to YouTube. The value is specified in ISO 8601 format.
From the spec of snippet.publishedAt, it follows that, in the case of a playlist being the uploads playlist of a given channel (that is a playlist of which ID is of form UU...; note that, usually, a channel ID and its corresponding uploads playlist ID are related by s/^UC([0-9a-zA-Z_-]{22})$/UU\1/, though not documented officially), the value of snippet.publishedAt is the upload date of that video.
The second spec, indicates that the value of contentDetails.videoPublishedAt is that of the corresponding Video resource's snippet.publishedAt, the time of publication of that video.
2. For the uploads playlist of a channel, the items returned by PlaylistItems.list API endpoint are (have to be) ordered in reverse chronological order by contentDetails.videoPublishedAt
Indeed, the ordering condition seems to be true. This feature is not documented officially, but, in my experience, the statement above holds true for every result set obtained from PlaylistItems.list endpoint.
I could make here the following argument justifying the necessity that the items resulted upon the invocation of PlaylistItems.list endpoint be ordered in reverse chronological order (newest first) by contentDetails.videoPublishedAt:
This argument is of a pragmatic kind: if the result set of PlaylistItems.list is not ordered as mentioned, then this endpoint becomes useless.
This is so, since, in this case, for one to obtain the most recently published video would have to fetch locally all the uploaded items (the number of which is limited by design to 20000), for to then scan that result set for the most recent one. Being compelled to fetch all uploaded items only for to obtain the newest one is pragmatically a nonsense. If the number of uploads of a given channel exceeds the limit of 20000, then the most recent video could possibly fall outside this boundary; thus, for such kind of channels, the most recently published video could not be obtained from the API at all.
Therefore, by way of contradiction, the result set has to be ordered in reverse chronological order by contentDetails.videoPublishedAt.

Is there a way to get more than 50 results from maxResults with the Youtube API?

I am trying to get a list of my subscribers using the Subscriptions: list. Is there a way to get values for all of my subscribers, or is it only possible to get 50 max? Is there another way to get values for all of my subscribers? I am aware the documentation says you can only get 50 results max, but I wanted to see if there was another way to get all the values. Thanks!
The max results you can get with 1 call is 50.
To get more results, you would need to make multiple calls. After the first call finishes and there are more results that can be obtained, the API call should return a string for the nextPageToken property. Use this for the optional pageToken parameter for your next API call. Repeat this process until you've obtained all the results.
Yes! Take a look at the pageToken parameter listed in the docs:
The relevant description is:
The pageToken parameter identifies a specific page in the result set that should be
returned. In an API response, the nextPageToken and prevPageToken properties identify
other pages that could be retrieved.

How to get all total result data by youtube api?

I am using Youtube Api to get all videos details of channel
https://www.googleapis.com/youtube/v3/search?part=snippet,id&key=XXXXXXXX&channelId=UCq-Fj5jknLsUf-MWSy4_brA&order=date&maxResults=50
You can see response
In the first response, I can see there are 761525 results and nextPageToken is also there but using that next page token I can max 300 to 400 video details after that API not giving me any result.
So is there any other to get all the videos details? Or anything is missing by me?
YouTube returns a soft limit of 500 videos for any search request.
If there are more than that in totalResults, you can split the search query using the publishedAfter and publishedBefore filters to loop through dates by day/week/month etc., making sure each 'time window' returns less than the 500 limit. Eventually, you will get all results.
After the first time you request an API call, for example this:
https://www.googleapis.com/youtube/v3/search?part=snippet,id&key=XXXXXXXX&channelId=UCq-Fj5jknLsUf-MWSy4_brA&order=date&maxResults=50
You need to fetch the nextPageToken parameter of that (1st) result , and feed it to the next (2nd) request. Let's suppose the nextPageToken of the first result is ABCDEFG, your next request must be like this:
https://www.googleapis.com/youtube/v3/search?part=snippet&pageToken=ABCDEFG,id&key=XXXXXXXX&channelId=UCq-Fj5jknLsUf-MWSy4_brA&order=date&maxResults=50
See that after snippet I've added &pageToken=ABCDEFG. And then you take again the string of the parameter nextPageToken of this (2nd) result and feed it to your next (3rd) request. So you need to do this with a while loop until the nextPageToken is null, which means you've hit the border number (in your case 761525 results). Or you can fix this by a certain number of results that you get.
Summary:
Request your first API call
Make a loop
Take the nextPageToken value
For your next requests, add after snippet this part &pageToken=
Write the value of nextPageToken after &pageToken=
Repeat from step 2 until a certain condition (until you get all the results or just a certain number of results)

Youtube v3 API "id" query parameter length

I am using the Youtube v3 api (video list function) to retrieve the statistics for some videos uploaded by a client. I filter the list by the video ids.
Does anyone have any idea how long the "id" parameter could be for such request? The reference only states this:
id - string - The id parameter specifies a comma-separated list of the YouTube video ID(s) for the resource(s) that are being retrieved. In a video resource, the id property specifies the video's ID.
In theory 50 IDs... you technically can only query 50 videos at a time, so unless you use next page tokens and keep the IDs, you're limited to 50... Personally I wouldn't go above 50 at a time...

Accessing an item beyond start_index=1000 in a YouTube user upload feed

I am currently trying to pull data about videos from a YouTube user upload feed. This feed contains all of the videos uploaded by a certain user, and is accessed from the API by a request to:
http://gdata.youtube.com/feeds/api/users/USERNAME/uploads
Where USERNAME is the name of the YouTube user who owns the feed.
However, I have encountered problems when trying to access feeds which are longer than 1000 videos. Since each request to the API can return 50 items, I am iterating through the feed using max_length and start_index as follows:
http://gdata.youtube.com/feeds/api/users/USERNAME/uploads?start-index=1&max-results=50&orderby=published
http://gdata.youtube.com/feeds/api/users/USERNAME/uploads?start-index=51&max-results=50&orderby=published
And so on, incrementing start_index by 50 on each call. This works perfectly up until:
http://gdata.youtube.com/feeds/api/users/USERNAME/uploads?start-index=1001&max-results=50&orderby=published
At which point I receive a 400 error informing me that 'You cannot request beyond item 1000.' This confused me as I assumed that the query would have only returned 50 videos: 1001-1051 in the order of most recently published. Having looked through the documentation, I discovered this:
Limits on result counts and accessible results
...
For any given query, you will not be able to retrieve more than 1,000
results even if there are more than that. The API will return an error
if you try to retrieve greater than 1,000 results. Thus, the API will
return an error if you set the start-index query parameter to a value
of 1001 or greater. It will also return an error if the sum of the
start-index and max-results parameters is greater than 1,001.
For example, if you set the start-index parameter value to 1000, then
you must set the max-results parameter value to 1, and if you set the
start-index parameter value to 980, then you must set the max-results
parameter value to 21 or less.
I am at a loss about how to access a generic user's 1001st last uploaded video and beyond in a consistent fashion, since they cannot be indexed using only max-results and start-index. Does anyone have any useful suggestions for how to avoid this problem? I hope that I've outlined the difficulty clearly!
Getting all the videos for a given account is supported, but you need to make sure that your request for the uploads feed is going against the backend database and not the search index. Because you're including orderby=published in your request URL, you're going against the search index. Search index feeds are limited to 1000 entries.
Get rid of the orderby=published and you'll get the data you're looking for. The default ordering of the uploads feed is reverse-chronological anyway.
This is a particularly easy mistake to make, and we have a blog post up explaining it in more detail:
http://apiblog.youtube.com/2012/03/keeping-things-fresh.html
The nice thing is that this is something that will no longer be a problem in version 3 of the API.

Resources