When I use the test form on the page https://developers.google.com/youtube/v3/docs/channels/list to get my upload ID I do not get the upload ID information in the output.
200 OK
- HIDE HEADERS -
cache-control: private, max-age=0, must-revalidate, no-transform
content-encoding: gzip
content-length: 184
content-type: application/json; charset=UTF-8
date: Sun, 20 Sep 2015 05:09:05 GMT
etag: "jOXstHOM20qemPbHbyzf7ztZ7rI/Z9n3n2b5RwRnE9WNo9TXpCBWbY4"
expires: Sun, 20 Sep 2015 05:09:05 GMT
server: GSE
vary: Origin, X-Origin
{
"kind": "youtube#channelListResponse",
"etag": "\"jOXstHOM20qemPbHbyzf7ztZ7rI/Z9n3n2b5RwRnE9WNo9TXpCBWbY4\"",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 5
},
"items": [
]
}
The command being used to generate this request is
GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=StraconisChannel
The part that confuses me is I'm doing the same thing as suggested by a tutorial I was following, the only thing I'm changing is the channel name and using my channel name instead. His output looks like this:
200 OK
- HIDE HEADERS -
cache-control: private, max-age=0, must-revalidate, no-transform
content-encoding: gzip
content-length: 350
content-type: application/json; charset=UTF-8
date: Sun, 20 Sep 2015 05:15:54 GMT
etag: "jOXstHOM20qemPbHbyzf7ztZ7rI/ih1aNGvKXcChCR4os4iGDwWDjmQ"
expires: Sun, 20 Sep 2015 05:15:54 GMT
server: GSE
vary: Origin, X-Origin
{
"kind": "youtube#channelListResponse",
"etag": "\"jOXstHOM20qemPbHbyzf7ztZ7rI/ih1aNGvKXcChCR4os4iGDwWDjmQ\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 5
},
"items": [
{
"kind": "youtube#channel",
"etag": "\"jOXstHOM20qemPbHbyzf7ztZ7rI/vDeq-1ACEYq89nbPsEZtYt0KNW0\"",
"id": "UC29ju8bIPH5as8OGnQzwJyA",
"contentDetails": {
"relatedPlaylists": {
"likes": "LL29ju8bIPH5as8OGnQzwJyA",
"favorites": "FL29ju8bIPH5as8OGnQzwJyA",
"uploads": "UU29ju8bIPH5as8OGnQzwJyA"
},
"googlePlusUserId": "111890735795696959293"
}
}
]
}
The request used for his results:
GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=techguyweb
I activated the Authorization using OAuth 2.0 so I'm not sure what the issue is.
Edit
A comment stated because it was my youtube username and not my google plus account name. I forgot to put this in to provided information as well. Which is the same result.
200 OK
- HIDE HEADERS -
cache-control: private, max-age=0, must-revalidate, no-transform
content-encoding: gzip
content-length: 184
content-type: application/json; charset=UTF-8
date: Sun, 20 Sep 2015 14:10:14 GMT
etag: "jOXstHOM20qemPbHbyzf7ztZ7rI/Z9n3n2b5RwRnE9WNo9TXpCBWbY4"
expires: Sun, 20 Sep 2015 14:10:14 GMT
server: GSE
vary: Origin, X-Origin
{
"kind": "youtube#channelListResponse",
"etag": "\"jOXstHOM20qemPbHbyzf7ztZ7rI/Z9n3n2b5RwRnE9WNo9TXpCBWbY4\"",
"pageInfo": {
"totalResults": 0,
"resultsPerPage": 5
},
"items": [
]
}
It returns the correct response if you specify channel ID instead of channel name (I got the information via HTTP request but it should work the same for the way you're trying to get the response).
{
"kind": "youtube#channelListResponse",
"etag": "\"jOXstHOM20qemPbHbyzf7ztZ7rI/pZlhvAUywQ74J9YlQvQ1UqIqanc\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
},
"items": [
{
"kind": "youtube#channel",
"etag": "\"jOXstHOM20qemPbHbyzf7ztZ7rI/iPoXCMXPqVZgATwZUSDCg0QqeCM\"",
"id": "UCoyAhNWQms1nSgGbI3rVebQ",
"snippet": {
"title": "StraconisChannel",
"description": "",
"publishedAt": "2015-09-08T22:33:23.000Z",
"thumbnails": {
"default": {
"url": "https://yt3.ggpht.com/-Yyqu34zJ9zs/AAAAAAAAAAI/AAAAAAAAAAA/tjDa1pW2Smw/s88-c-k-no/photo.jpg"
},
"medium": {
"url": "https://yt3.ggpht.com/-Yyqu34zJ9zs/AAAAAAAAAAI/AAAAAAAAAAA/tjDa1pW2Smw/s240-c-k-no/photo.jpg"
},
"high": {
"url": "https://yt3.ggpht.com/-Yyqu34zJ9zs/AAAAAAAAAAI/AAAAAAAAAAA/tjDa1pW2Smw/s240-c-k-no/photo.jpg"
}
},
"localized": {
"title": "StraconisChannel",
"description": ""
},
"country": "US"
},
"contentDetails": {
"relatedPlaylists": {
"uploads": "UUoyAhNWQms1nSgGbI3rVebQ"
},
"googlePlusUserId": "108236998864115482919"
}
}
]
}
Make sure you have verified your YouTube channel and connected your channel to a Google+ Page or Profile.
Related
First step:
I sent GET request
curl --location --request GET 'https://www.googleapis.com/youtube/v3/videos?key={API_KEY}&part=id&chart=mostPopular®ionCode=es&videoCategoryId=17&maxResults=25'
I received 200 OK response, body:
{
"kind": "youtube#videoListResponse",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/CcRzMe1sxt_kvnG7LpS3dIQoCig\"",
"nextPageToken": "CBkQAA",
"pageInfo": {
"totalResults": 181,
"resultsPerPage": 25
},
"items": [
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/_GxV3cYD2wcterTfViCosiAVb54\"",
"id": "LGnQfH8dnow"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/-qYNOMCfpr8knbAS5auTTwRVt5Q\"",
"id": "3cO8sTv9aE4"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/4VBqB7u16yEkTMk6sSYEOI4P-hs\"",
"id": "8-7b4Ixavrg"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/ppyJEw0-OpZ3VI56IIn4vwl6Ja8\"",
"id": "tZvxbUosFWw"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/qk0x2ve66gTYW6_g8O4BWlfrvJU\"",
"id": "_4-KEZw9bX4"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/XP7oKSr0MwfURXwaW5nr1Qi8WbE\"",
"id": "sgERdPX_dkM"
},
...(other videos...)
]
}
I saved body.etag value in cache, on my side. This value: "etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/CcRzMe1sxt_kvnG7LpS3dIQoCig\""
I sent the same GET request one more time, but i added If-None-Match: "tnVOtk4NeGU6nDncDTE5m9SmuHc/CcRzMe1sxt_kvnG7LpS3dIQoCig" HTTP header to this GET request.
curl --location --request GET 'https://www.googleapis.com/youtube/v3/videos?key={API_KEY}&part=id&chart=mostPopular®ionCode=es&videoCategoryId=17&maxResults=25' \
--header 'If-None-Match: "tnVOtk4NeGU6nDncDTE5m9SmuHc/CcRzMe1sxt_kvnG7LpS3dIQoCig"'
I received 200 OK response, body:
{
"kind": "youtube#videoListResponse",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/_ruxn7w4X-iRBUUok6BWY66DtLU\"",
"nextPageToken": "CBkQAA",
"pageInfo": {
"totalResults": 181,
"resultsPerPage": 25
},
"items": [
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/_GxV3cYD2wcterTfViCosiAVb54\"",
"id": "LGnQfH8dnow"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/-qYNOMCfpr8knbAS5auTTwRVt5Q\"",
"id": "3cO8sTv9aE4"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/4VBqB7u16yEkTMk6sSYEOI4P-hs\"",
"id": "8-7b4Ixavrg"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/ppyJEw0-OpZ3VI56IIn4vwl6Ja8\"",
"id": "tZvxbUosFWw"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/qk0x2ve66gTYW6_g8O4BWlfrvJU\"",
"id": "_4-KEZw9bX4"
},
{
"kind": "youtube#video",
"etag": "\"tnVOtk4NeGU6nDncDTE5m9SmuHc/XP7oKSr0MwfURXwaW5nr1Qi8WbE\"",
"id": "sgERdPX_dkM"
},
...(other videos...)
]
}
I expect to receive 304 not modified, not 200 OK and the same result.
But i still to receive 200 OK and new etag in response body. See the screenshoot.
I expect to have only one first response. I expect to receive 304 when i request the same query with If-None-Match: "tnVOtk4NeGU6nDncDTE5m9SmuHc/CcRzMe1sxt_kvnG7LpS3dIQoCig" cause no changes in requested data.
We are seeing what appears to be a change in the behavior of the Graph API. Our code, which grants access for an Excel workbook in OneDrive to a specific Security Group, is now failing where it used to succeed.
Request:
POST https://graph.microsoft.com/V1.0/groups/d4826b5d-4106-40a6-97e0-3826dff58e17/drive/root:/sageData/_verbs.xlsx:/invite HTTP/1.1
Accept: application/json
Authorization: Bearer <<token omitted>>
Content-Type: application/json; charset=utf-8
Host: graph.microsoft.com
Content-Length: 127
Expect: 100-continue
Connection: Keep-Alive
{
"recipients": [{
"alias": "d536e908-60cb-4558-8b3a-38f033d6508a"
}],
"requireSignIn": true,
"sendInvitation": false,
"roles": ["Write"]
}
Response:
HTTP/1.1 404 Not Found
Cache-Control: private
Content-Type: application/json
request-id: 48f148b6-0c15-410e-b29d-bef5880c7007
client-request-id: 48f148b6-0c15-410e-b29d-bef5880c7007
x-ms-ags-diagnostic: {"ServerInfo":{"DataCenter":"North Europe","Slice":"SliceB","Ring":"NA","ScaleUnit":"001","Host":"AGSFE_IN_14","ADSiteName":"DUB"}}
Duration: 981.5167
Date: Wed, 15 Nov 2017 13:05:50 GMT
Content-Length: 247
{
"error": {
"code": "itemNotFound",
"message": "One of the provided recipients could not be found",
"innerError": {
"request-id": "48f148b6-0c15-410e-b29d-bef5880c7007",
"date": "2017-11-15T13:05:51"
}
}
}
However, we can see that "recipient"" (which is the Security Group id) does indeed exist:
GET https://graph.microsoft.com/v1.0/groups/d536e908-60cb-4558-8b3a-38f033d6508a
Response
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#groups/$entity",
"id": "d536e908-60cb-4558-8b3a-38f033d6508a",
"deletedDateTime": null,
"classification": null,
"createdDateTime": "2017-11-15T12:42:01Z",
"description": "{\"datasetIdentifier\":\"4122e61b-d5c1-4a58-9068-dfdeda9e8278\",\"roleIdentifier\":\"FullAccess\",\"isSageMetadata\":true,\"type\":\"Role\"}",
"displayName": "Sage - Pete - All Apps & Add-Ins",
"groupTypes": [],
"mail": null,
"mailEnabled": false,
"mailNickname": "Sage-Pete-AllApps-Add-Ins",
"onPremisesLastSyncDateTime": null,
"onPremisesProvisioningErrors": [],
"onPremisesSecurityIdentifier": null,
"onPremisesSyncEnabled": null,
"proxyAddresses": [],
"renewedDateTime": "2017-11-15T12:42:01Z",
"securityEnabled": true,
"visibility": null
}
The documentation states the recipient property we are posting should be "email" whereas we have used "alias" up to this point. If we change to "email" then it works.
However, that seems incorrect, according to the documentation we should use alias:
"The alias of the domain object, for cases where an email address is unavailable (e.g. security groups)."
Has anyone else encountered this behaviour?
What you're submitting as an alias is actually an objectId. The alias in this case would be the object's mailNickname (i.e. Sage-Pete-AllApps-Add-Ins).
Either of these should work:
{
"recipients": [{
"objectId": "d536e908-60cb-4558-8b3a-38f033d6508a"
}],
"requireSignIn": true,
"sendInvitation": false,
"roles": ["Write"]
}
or
{
"recipients": [{
"alias": "Sage-Pete-AllApps-Add-Ins"
}],
"requireSignIn": true,
"sendInvitation": false,
"roles": ["Write"]
}
How do I update the item's position in the playlist?
I used API Explorer:
https://developers.google.com/youtube/v3/docs/playlistItems/update#try-it
part: snippet
Request body:
{
"id": "12345",
"snippet":
{
"playlistId": "my_playlist_id",
"resourceId":
{
"kind": "youtube#video",
"videoId": "my_video_id"
},
"position": 3
}
}
Response:
403 Forbidden
Cache-Control: private, max-age=0
Content-Encoding: gzip
Content-Length: 125
Content-Type: application/json; charset=UTF-8
Date: Sun, 28 Apr 2013 14:23:37 GMT
Expires: Sun, 28 Apr 2013 14:23:37 GMT
Server: GSE
{
"error": {
"errors": [
{
"domain": "youtube.common",
"reason": "forbidden",
"message": "Forbidden"
}
],
"code": 403,
"message": "Forbidden"
}
}
I tried it and I think the API call works correctly:
Request
PUT https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2CcontentDetails%2Cstatus&fields=id%2Csnippet&key={YOUR_API_KEY}
Content-Type: application/json
X-JavaScript-User-Agent: Google APIs Explorer
{
"id": "PLSvpjjbPJQDXYjfamKNrJHvyvkBfr7n1QwkVWH-4kWwk",
"snippet": {
"playlistId": "PLF-2B3_5y4x_yqhdqjdrXuse2AcK7i3XE",
"resourceId": {
"kind": "youtube#video",
"videoId": "MP1gvGcXcLk"
},
"position": 1
}
}
Response
200 OK
- Show headers -
{
"id": "PLSvpjjbPJQDXYjfamKNrJHvyvkBfr7n1QwkVWH-4kWwk",
"snippet": {
"publishedAt": "2013-03-01T16:33:20.000Z",
"channelId": "UC4_r417bYTsCoaVGgH1yYTg",
"title": "Amazing Google Glasses Demonstration at Google I/O 2012",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/MP1gvGcXcLk/default.jpg"
},
"medium": {
"url": "https://i.ytimg.com/vi/MP1gvGcXcLk/mqdefault.jpg"
},
"high": {
"url": "https://i.ytimg.com/vi/MP1gvGcXcLk/hqdefault.jpg"
}
},
"channelTitle": "Matias Molinas",
"playlistId": "PLF-2B3_5y4x_yqhdqjdrXuse2AcK7i3XE",
"position": 1,
"resourceId": {
"kind": "youtube#video",
"videoId": "MP1gvGcXcLk"
}
}
}
maybe it is a quota error:
The remote server returned an error: (403) Forbidden in Youtube api
HTTP 403 responses can be associated with a number of different errors, and taking a look at the actual response HTTP body (or the serialized version of it reported in the exception.Response property) is the only way of determining the exact cause.
A very common cause of 403s when performing uploads are quota errors, though. Here are more details:
http://apiblog.youtube.com/2010/02/best-practices-for-avoiding-quota.html
Per the v3 API spec, videos that come back in searches should contain thumbnails.
Up until 30 minutes ago, that was the case.
However, now, the API is returning videos with no "thumbnails" attribute in the JSON.
For example:
https://www.googleapis.com/youtube/v3/videos?part=snippet&key=(key)&id=Kq9z1gNjl0o
Previously would return:
{
"kind": "youtube#videoListResponse",
"etag": "\"idnvT0N6oxG_2o6LCWUdZsqtqtk/flm_N0PUouBHj2piDWTowbpXlNM\"",
"items": [
{
"id": "Kq9z1gNjl0o",
"kind": "youtube#video",
"etag": "\"idnvT0N6oxG_2o6LCWUdZsqtqtk/9f5tPPIkXNmECTi095h9jBWV0s0\"",
"snippet": {
"publishedAt": "2010-06-27T00:07:30.000Z",
"channelId": "UC3lizSW-J9kc8JR455mzv-w",
"thumbnails": [
"small": {
"url": "http://ytimg.com/someimage.jpg"
}
]
"title": "Kristen Bell - On Craig Ferguson - 4/19/08 - Wow",
"description": "Interview",
"channelTitle": "stewiefan33",
"categoryId": "22"
}
}
]
}
Now returns:
{
"kind": "youtube#videoListResponse",
"etag": "\"idnvT0N6oxG_2o6LCWUdZsqtqtk/flm_N0PUouBHj2piDWTowbpXlNM\"",
"items": [
{
"id": "Kq9z1gNjl0o",
"kind": "youtube#video",
"etag": "\"idnvT0N6oxG_2o6LCWUdZsqtqtk/9f5tPPIkXNmECTi095h9jBWV0s0\"",
"snippet": {
"publishedAt": "2010-06-27T00:07:30.000Z",
"channelId": "UC3lizSW-J9kc8JR455mzv-w",
"title": "Kristen Bell - On Craig Ferguson - 4/19/08 - Wow",
"description": "Interview",
"channelTitle": "stewiefan33",
"categoryId": "22"
}
}
]
}
The "thumbnails" field is gone, but still in the doc. Is this a bug in the API?
How do I list the user's uploaded videos in the V3 api?
If you are using the client then Greg's answer is correct. To do the same thing with basic requests you make the following 2 requests:
GET https://www.googleapis.com/youtube/v3/channels
with parameters:
part=contentDetails
mine=true
key={YOUR_API_KEY}
and header:
Authorization: Bearer {Your access token}
From this you will get a JSON response like so:
{
"kind": "youtube#channelListResponse",
"etag": "\"some-string\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 1
},
"items": [
{
"id": "some-id",
"kind": "youtube#channel",
"etag": "\"another-string\"",
"contentDetails": {
"relatedPlaylists": {
"likes": "channel-id-for-your-likes",
"favorites": "channel-id-for-your-favorites",
"uploads": "channel-id-for-your-uploads",
"watchHistory": "channel-id-for-your-watch-history",
"watchLater": "channel-id-for-your-watch-later"
}
}
}
]
}
From this you want to parse out the "uploads" channel-id.
GET https://www.googleapis.com/youtube/v3/playlistItems
with parameters:
part=snippet
maxResults=50
id={YOUR_UPLOAD_PLAYLIST_ID}
key={YOUR_API_KEY}
and headers:
Authorization: Bearer {YOUR_TOKEN}
From this you will receive a JSON response like the following:
{
"kind": "youtube#playlistItemListResponse",
"etag": "\"some-string\"",
"pageInfo": {
"totalResults": 1,
"resultsPerPage": 50
},
"items": [
{
"id": "some-id",
"kind": "youtube#playlistItem",
"etag": "\"another-string\"",
"snippet": {
"publishedAt": "some-date",
"channelId": "the-channel-id",
"title": "video-title",
"thumbnails": {
"default": {
"url": "thumbnail-address"
},
"medium": {
"url": "thumbnail-address"
},
"high": {
"url": "thumbnail-address"
}
},
"playlistId": "upload-playlist-id",
"position": 0,
"resourceId": {
"kind": "youtube#video",
"videoId": "the-videos-id"
}
}
}
]
}
With this method you should be able to get the info using any language or even just curl. If you want more than the first 50 results, then you will have to do multiple queries using the second request and pass in page requests. More on this can be read at: http://developers.google.com/youtube/v3/docs/playlistItems/list
The first step is getting the channel id for that user. We can do this with request to the Channels service. Here's a JS example.
var request = gapi.client.youtube.channels.list({
// mine: true indicates that we want to retrieve the channel for the authenticated user.
mine: true,
part: 'contentDetails'
});
request.execute(function(response) {
playlistId = response.result.channels[0].contentDetails.uploads;
});
Once we get the playlist id we can use that to query for the list of uploaded videos from the PlaylistItems service.
var request = gapi.client.youtube.playlistItems.list({
id: playlistId,
part: 'snippet',
});
request.execute(function(response) {
// Go through response.result.playlistItems to view list of uploaded videos.
});