## Required authorization scopes

The Google Photos Library API contains multiple scopes used to access media items and albums.
The media items returned from various calls are different based on which scopes
have been requested by the developer.

The `photoslibrary.readonly` scope allows access to all media items in the
user's library. The `photoslibrary.readonly.appcreateddata` scope allows access
only to media items that were created by the app. For more information, see
[Authorization scopes](https://developers.google.com/photos/library/legacy/guides/authorization.md.txt).

## Overview

An important use of the API is to list media items that the user has backed up
to Google Photos. Items in a particular album or from the user's entire
library (the default view in the Google Photos app) can be listed.

You can [use filters to select photos](https://developers.google.com/photos/library/legacy/guides/apply-filters.md.txt)
that match a specified date, content category, or media type when you list items
from the user's library. This feature isn't supported when you list items from
albums.

Listing the library and album contents returns a list of media items.
[Enrichments](https://developers.google.com/photos/library/legacy/guides/add-enrichments.md.txt) that are part of an album
aren't included. Media items describe a photo, video, or other media. A
`mediaItem` includes a direct link to the item, a link to the item in
Google Photos, and other relevant metadata. For more information, see
[Access media items](https://developers.google.com/photos/library/legacy/guides/access-media-items.md.txt) and
[`mediaItems`](https://developers.google.com/photos/library/legacy/reference/rest/v1/mediaItems.md.txt).

> [!CAUTION]
> **Caution:** Don't cache user photos and videos. Instead, store the media item `id` and request its details again when you need them. Images may change, and direct access through the `baseUrl` expires after 60 minutes. For more information, see [Access media items](https://developers.google.com/photos/library/legacy/guides/access-media-items.md.txt).

## Listing albums

You can retrieve a list of the user's albums using
[albums.list](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums/list.md.txt).

### REST

Here is a sample request:

```
GET https://photoslibrary.googleapis.com/v1/albums
```

The request returns the following result:

```restructuredtext
{
  "albums": [
    {
      "id": "album-id",
      "title": "album-title",
      "productUrl": "album-product-url",
      "coverPhotoBaseUrl": "album-cover-base-url_do-not-use-directly",
      "coverPhotoMediaItemId": "album-cover-media-item-id",
      "isWriteable": "whether-you-can-write-to-this-album",
      "mediaItemsCount": "number-of-media-items-in-album"
    },
    ...
  ],
  "nextPageToken": "token-for-pagination"
}
```

### Java

```java
try {
  // Make a request to list all albums in the user's library
  // Iterate over all the albums in this list
  // Pagination is handled automatically
  ListAlbumsPagedResponse response = photosLibraryClient.listAlbums();

  for (Album album : response.iterateAll()) {
    // Get some properties of an album
    String id = album.getId();
    String title = album.getTitle();
    String productUrl = album.getProductUrl();
    String coverPhotoBaseUrl = album.getCoverPhotoBaseUrl();
    // The cover photo media item id field may be empty
    String coverPhotoMediaItemId = album.getCoverPhotoMediaItemId();
    boolean isWritable = album.getIsWriteable();
    long mediaItemsCount = album.getMediaItemsCount();
  }

} catch (ApiException e) {
  // Handle error
}
```

### PHP

```php
try {
    // Make a request to list all albums in the user's library
    // Iterate over all the albums in this list
    // Pagination is handled automatically
    $response = $photosLibraryClient->listAlbums();
    foreach ($response->iterateAllElements() as $album) {
        // Get some properties of an album
        $albumId = $album->getId();
        $title = $album->getTitle();
        $productUrl = $album->getProductUrl();
        $coverPhotoBaseUrl = $album->getCoverPhotoBaseUrl();
        // The cover photo media item id field may be empty
        $coverPhotoMediaItemId = $album->getCoverPhotoMediaItemId();
        $isWriteable = $album->getIsWriteable();
        $totalMediaItems = $album->getTotalMediaItems();
    }
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}
```

Each returned album has an ID that can be used to retrieve the contents of the
album as shown in [Listing album contents](https://developers.google.com/photos/library/legacy/guides/list.md.txt#listing-album-contents). It also
includes the title and the number of media items it contains.

The `productUrl` points to the album in Google Photos that can be a
opened by the user.

The `coverPhotoMediaItemId` contains the [media item
ID](https://developers.google.com/photos/library/legacy/reference/rest/v1/mediaItems) that
represents the cover photo of this album. To the access this cover image, use
`coverPhotoBaseUrl`. You shouldn't use the `coverPhotoBaseUrl` directly without
specifying [additional
parameters](https://developers.google.com/photos/library/legacy/guides/access-media-items#base-urls).

Albums that have been created in the user's account or added to the user's
account and that your app has shared include an additional `shareInfo` property.
For more details, see [Share media](https://developers.google.com/photos/library/legacy/guides/share-media.md.txt).

Albums may also have an `isWriteable` flag to indicate if you can create media
items in the album. This flag defaults to `false` if it is not returned. It is
dependent on the access granted to your application, including the following:

- Who created the album.
- If it's shared or not.
- What [scopes](https://developers.google.com/photos/library/legacy/guides/authorization.md.txt) the user has approved.

This flag may change if any of these criteria change. For more details, see
[Create albums](https://developers.google.com/photos/library/legacy/guides/manage-albums.md.txt#creating-new-album). The
response also contains a `nextPageToken`. For more information, see
[Pagination](https://developers.google.com/photos/library/legacy/guides/list.md.txt#pagination).

The response for empty albums varies in that, `mediaItemsCount` and
`coverPhotoMediaItemId` are set to 0 by default and are omitted from the REST
response. Also note that `coverPhotoBaseUrl` points to a default placeholder
image.

## Listing library contents

You can list all the media items from the user's Google Photos library.
It excludes archived and deleted items. You can list media items based on their
content, date, and other properties by [applying
filters](https://developers.google.com/photos/library/legacy/guides/apply-filters). If the user has not added an
item available in the **Sharing** tab of their Google Photos to their
library, that item is not included in this list.

To retrieve a media item, call
[mediaItems.list](https://developers.google.com/photos/library/legacy/reference/rest/v1/mediaItems/list.md.txt).

### REST

Here is a sample request:

```restructuredtext

{
  "pageSize": "100",
}
```

The GET request returns the following response:

```restructuredtext
{
  "mediaItems": [
    ...
  ],
  "nextPageToken": "token-for-pagination"
}
```

### Java

```java
try {
  // Make a request to list all media items in the user's library
  // Iterate over all the retrieved media items
  // Pagination is handled automatically
  ListMediaItemsPagedResponse response = photosLibraryClient.listMediaItems();
  for (MediaItem item : response.iterateAll()) {
    // Get some properties of a media item
    String id = item.getId();
    String description = item.getDescription();
    String mimeType = item.getMimeType();
    String productUrl = item.getProductUrl();
    String filename = item.getFilename();
  }
} catch (ApiException e) {
  // Handle error
}
```

### PHP

```php
try {
    // Make a request to list all media items in the user's library
    // Iterate over all the retrieved media items
    // Pagination is handled automatically
    $response = $photosLibraryClient->listMediaItems();
    foreach ($response->iterateAllElements() as $item) {
        // Get some properties of a media item
        /* @var $item \Google\Photos\Library\V1\MediaItem */
        $id = $item->getId();
        $description = $item->getDescription();
        $mimeType = $item->getMimeType();
        $productUrl = $item->getProductUrl();
        $filename = $item->getFilename();
    }
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}
```

The response contains a list of media items, ordered from most to least recent.
For more information, see
[`mediaItems`](https://developers.google.com/photos/library/legacy/reference/rest/v1/mediaItems.md.txt#MediaItem). It also
contains a `nextPageToken`, which is described in more detail in
[Pagination](https://developers.google.com/photos/library/legacy/guides/list.md.txt#pagination).

## Listing album contents

To list all of the media items in an album, add the `albumId` field to your
search request. For more information about `albumId`, see [Listing
albums](https://developers.google.com/photos/library/legacy/guides/list#listing-albums) and [Listing shared albums](https://developers.google.com/photos/library/legacy/guides/list.md.txt#listing-shared-albums). If
the `albumId` is invalid, a `Bad Request` error is returned. If the ID is valid,
but the album doesn't exist for the authenticated user, a `Not Found` error is
returned. For more details regarding error handling,see [Performance
tips](https://developers.google.com/photos/library/legacy/guides/performance-tips) and [Best
practices](https://developers.google.com/photos/library/legacy/guides/best-practices).

### REST

Here is a sample request:

```restructuredtext

{
  "pageSize": "100",
  "albumId": "album-id"
}
```

The POST request returns the following response:

```restructuredtext
{
  "mediaItems": [
    ...
  ],
  "nextPageToken": "token-for-pagination"
}
```

### Java

```java
try {
  // Make a request to list all media items in an album
  // Provide the ID of the album as a parameter in the searchMediaItems call
  // Iterate over all the retrieved media items
  SearchMediaItemsPagedResponse response = photosLibraryClient.searchMediaItems(albumId);

  for (MediaItem item : response.iterateAll()) {
    // ...
  }

} catch (ApiException e) {
  // Handle error
}
```

### PHP

```php
try {
    // Make a request to list all media items in an album
    // Provide the ID of the album as a parameter in the searchMediaItems call
    // Iterate over all the retrieved media items
    $response = $photosLibraryClient->searchMediaItems(['albumId' => $albumId]);
    foreach ($response->iterateAllElements() as $item) {
        // ...
    }
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}
```

The response contains a `nextPageToken` and the list of media items. Unlike when
listing library contents, the media items are returned by their order in the
album. For more details, see
[`mediaItems`](https://developers.google.com/photos/library/legacy/reference/rest/v1/mediaItems.md.txt)
and [Pagination](https://developers.google.com/photos/library/legacy/guides/list.md.txt#pagination). The user can edit the order in the
Google Photos interface.

If the `albumId` is set, you can't apply a filter when listing album contents.
Doing so results in a `Bad Request` error.

## Listing shared albums

You can retrieve a list of all albums that the user has shared or that have been
shared with a user. This is similar to the Sharing tab in the
Google Photos app.

Shared albums that the user has added to their Google Photos library
are also returned in the [listing albums](https://developers.google.com/photos/library/legacy/guides/list.md.txt#listing-albums) call. Make the
following call to list shared albums through the Library API:

### REST

Here is a sample request:

```
GET https://photoslibrary.googleapis.com/v1/sharedAlbums
```

The request returns the following result:

```restructuredtext
{
  "sharedAlbums": [...]
  "nextPageToken": "token-for-pagination"
}
```

### Java

```java
try {
  // Make a request to list all albums that have been shared by the user
  // Iterate over all the albums in this list
  // Pagination is handled automatically
  ListSharedAlbumsPagedResponse response = photosLibraryClient.listSharedAlbums();

  for (Album album : response.iterateAll()) {
    // ..
  }

} catch (ApiException e) {
  // Handle error
}
```

### PHP

```php
try {
    // Make a request to list all albums that have been shared by the user
    // Iterate over all the albums in this list
    // Pagination is handled automatically
    $response = $photosLibraryClient->listSharedAlbums();
    foreach ($response->iterateAllElements() as $album) {
        // ...
    }
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}
```

A list of albums is included in `sharedAlbums`. For more information, see
[Listing albums](https://developers.google.com/photos/library/legacy/guides/list.md.txt#listing-albums). The response also contains a `nextPageToken`.
For more information, see [Pagination](https://developers.google.com/photos/library/legacy/guides/list.md.txt#pagination).

Albums that your app has created and shared include an additional `shareInfo`
property. For more details, see [Share
media](https://developers.google.com/photos/library/legacy/guides/share-media).

## Listing app created albums

You can list albums that have been created by your app with
`excludeNonAppCreatedData` set to `true` in the following calls:

- [`albums.list`](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums/list.md.txt)
- [`sharedAlbums.list`](https://developers.google.com/photos/library/legacy/reference/rest/v1/sharedAlbums/list.md.txt)

### REST

Here is a GET request to list all the albums from the user's
Google Photos library created only by your app:

```
GET https://photoslibrary.googleapis.com/v1/albums?excludeNonAppCreatedData=true
Content-type: application/json
Authorization: Bearer oauth2-token
```

Here is a GET request to list all the shared albums from the user's
Google Photos library created only by your app:

```
GET https://photoslibrary.googleapis.com/v1/sharedAlbums?excludeNonAppCreatedData=true
Content-type: application/json
Authorization: Bearer oauth2-token
```

### Java

```java
try {
  // Make a request to list all albums that have been created by your app
  boolean excludeNonAppCreatedData = true;

  // Iterate over all the albums in this list
  // Pagination is handled automatically
  ListAlbumsPagedResponse response = photosLibraryClient.listAlbums(excludeNonAppCreatedData);

  for (Album album : response.iterateAll()) {
    // ..
  }

} catch (ApiException e) {
  // Handle error
}

try {
  // Make a request to list all shared albums that have been created by your app
  boolean excludeNonAppCreatedData = true;

  // Iterate over all the albums in this list
  // Pagination is handled automatically
  ListSharedAlbumsPagedResponse response =
      photosLibraryClient.listSharedAlbums(excludeNonAppCreatedData);

  for (Album album : response.iterateAll()) {
    // ..
  }

} catch (ApiException e) {
  // Handle error
}
```

### PHP

```php
try {
    // Make a request to list all albums that have been created by your app
    $response = $photosLibraryClient->listAlbums(['excludeNonAppCreatedData' => true]);

    // Iterate over all the albums in this list
    // Pagination is handled automatically
    foreach ($response->iterateAllElements() as $album) {
        // ...
    }
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}

try {
    // Make a request to list all shared albums that have been created by your app
    $response = $photosLibraryClient->listSharedAlbums(['excludeNonAppCreatedData' => true]);

    // Iterate over all the albums in this list
    // Pagination is handled automatically
    foreach ($response->iterateAllElements() as $album) {
        // ...
    }
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}
```

## Pagination for REST

To improve performance, methods that return a large number of results (such as
list methods) may paginate the response. The maximum number of results in each
page is given by the `pageSize` parameter.

For calls to `mediaItems:search` and `mediaItems:list`, the default page size is
25 items. We recommend this page size because it strikes a balance between the
size of the response and the fill rate. The maximum page size for media item
search and list requests is 100 items.

The default and recommended page size when listing albums is 20 albums, with a
maximum of 50 albums.

When the number of available results is greater than the page size, the response
includes a `nextPageToken`, which indicates to your application that there are
more results to be fetched from the server.

> [!NOTE]
> **Note:** The `pageSize` parameter is a maximum --- fewer results might be returned than are requested.

### Example

You must append the `nextPageToken` to subsequent requests in the parameter
`pageToken`, as shown in the following example. Specify the `pageToken` together
with other parameters required for the operation, either in the body of the
request, or as a query parameter.

#### Request #1

```
{
  "pageSize": "5",
  "filters": { … }
}
```

#### Response #1

```
{
  "mediaItem": [ … ],
  "nextPageToken": "next-page-token"
}
```

#### Request #2

```
{
  "pageSize": "5",
  "filters": { … },
  "pageToken": "page-token"
}
```

#### Response #2

```
{
  "mediaItem": [ … ],
  "nextPageToken": "next-page-token"
}
```

Continue this pattern until there are no more `nextPageToken` objects.

The `nextPageToken` is only valid for the same request. If any parameters are
changed, a previously used `nextPageToken` shouldn't be used in the same
request.

> [!NOTE]
> **Note:** The existence of `nextPageToken` is the only indicator of whether or not there are more results to be fetched from the server. Don't count the number of results to determine if you should use your `nextPageToken`. A request may return fewer results than requested in the page size. If a `nextPageToken` is present, you can send a request for more results after your initial request.