In Google Photos, you can organize photos and other media items using albums.
A media item can be associated with one or more albums. To start associating
media items with an album, you need to create the album first.

## Required authorization scopes

To create an album, your app must request at least one of the following
[authorization scopes](https://developers.google.com/photos/library/legacy/guides/authorization.md.txt):

- `photoslibrary.appendonly`
- `photoslibrary.sharing`

To change the title or cover photo of albums after their creation, use the
`photoslibrary.edit.appcreateddata` scope.

## Creating a new album

To create an album, call
[`albums.create`](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums/create.md.txt) and include
the `title`. Note that `title` is restricted to 500 characters.

The call returns an
[album](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums.md.txt). Your app can
store the album ID from this information and use it for
[uploading media items](https://developers.google.com/photos/library/legacy/guides/upload-media.md.txt)
to the specific album.

### REST

Here is a header for a POST request:

```
POST https://photoslibrary.googleapis.com/v1/albums
Content-type: application/json
Authorization: Bearer oauth2-token
```

The request body looks like this:

```restructuredtext
{
  "album": {
    "title": "new-album-title"
  }
}
```

If successful, the response returns an
[album](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums.md.txt):

```restructuredtext
{
  "productUrl": "album-product-url",
  "id": "album-id",
  "title": "album-title",
  "isWriteable": "whether-you-can-write-to-this-album"
}
```

### Java

```java
try {
  Album createdAlbum = photosLibraryClient.createAlbum("My Album");
  // The createdAlbum object contains properties of an album
  String productUrl = createdAlbum.getProductUrl();
  // coverPhotoBaseUrl shouldn't be used as is. Append parameters to base URLs before use
  String albumCoverImage = createdAlbum.getCoverPhotoBaseUrl() + "=w2048-h1024";
  boolean isWriteable = createdAlbum.getIsWriteable();
} catch (ApiException e) {
  // Handle error
}
```

### PHP

```php
try {
    $newAlbum = PhotosLibraryResourceFactory::album("My Album");
    $createdAlbum = $photosLibraryClient->createAlbum($newAlbum);
    // The createdAlbum object contains properties of an album
    $albumId = $createdAlbum->getId();
    $productUrl = $createdAlbum->getProductUrl();
    // coverPhotoBaseUrl shouldn't be used as is. Append parameters to base URLs before use
    $albumCoverImage = $createdAlbum->getCoverPhotoBaseUrl() . '=w2048-h1024';
    $isWriteable = $createdAlbum->getIsWriteable();
} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}
```

## Changing album titles and cover photos

To change an album title or cover photo, make an [`album update
call`](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums/patch) with the
identifier of the album, and include the new title or the new cover photo's
media item ID in the request. You'll need to use the
`photoslibrary.edit.appcreateddata`
[authorization](https://developers.google.com/photos/library/legacy/guides/authorization.md.txt) scope to make the change.

Album titles can be no more than 500 characters in length. Cover media items
must be owned by the album owner, and belong to the album they will be a cover
for.

### REST

Here's a PATCH request header to update an album's `title` and
`coverPhotomediaItemId`.

```
PATCH https://photoslibrary.googleapis.com/v1/albums/album-id?updateMask=title&updateMask=coverPhotoMediaItemId
```

This request determines what properties are being updated by including
a field mask, indicated by the `updateMask` parameters in the
URL. The `updateMask` parameter needs to be passed for each
album property that is being updated.

For each property you are updating, include its details in
the body of the request:

```restructuredtext
{
  "title": "new-album-title",
  "coverPhotoMediaItemId": "new-cover-media-item-id"
}
```

If successful, the response returns the updated `album`
details:

```restructuredtext
{
  "id": "album-id",
  "title": "new-album-title",
  "productUrl": "album-product-url",
  "isWriteable": "true-if-user-can-write-to-this-album",
  "mediaItemsCount": "number-of-media-items-in-album",
  "coverPhotoBaseUrl": "cover-photo-base-url_use-only-with-parameters",
  "coverPhotoMediaItemId": "new-cover-media-item-id"
}
```

### Java

```java
try {
  // Update the cover photo of the album given a MediaItem object.
  Album updatedAlbum = photosLibraryClient.updateAlbumCoverPhoto(album, newCoverMediaItem);

  // Alternatively, you can update the cover photo of the album given a media item ID.
  // The specified media item identifier must be not null or empty.
  // Album updatedAlbum = photosLibraryClient.updateAlbumCoverPhoto(album, "new-cover-media-item-id");
} catch (ApiException e) {
  // Handle error
}
try {
  // Update the title of the album.
  // The new title must not be null or empty.
  Album updatedAlbum = photosLibraryClient.updateAlbumTitle(album, "new-album-title");
} catch (ApiException e) {
  // Handle error
}
```

### PHP

```php
try {

    // ID of the album to update.
    $albumId = "ALBUM_ID";

    // Media item ID of the new cover photo.
    // Must not be null or empty.
    $newCoverMediaItemId = "new-cover-media-item-id";

    // Update the cover photo of the album.
    $mediaItem = $photosLibraryClient->updateAlbumCoverPhoto($albumId, $newCoverMediaItemId);

} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}
try {

    // ID of the album to update.
    $albumId = "ALBUM_ID";

    // New title of the album.
    // Must not be null or empty.
    $newTitle = "new-album-title";

    // Update the title of the album.
    $mediaItem = $photosLibraryClient->updateAlbumTitle($albumId, $newTitle);

} catch (\Google\ApiCore\ApiException $e) {
    // Handle error
}
```

## Adding media items to an album

You can add media items from the user's Google Photos library to an album by
calling
[`albums.batchAddMediaItems`](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums/batchAddMediaItems.md.txt).
Media items are added to the end of the album in the order given in this call.

The entire request will fail if an invalid media item or album is specified.
Partial success is not supported.

Each album can contain up to 20,000 media items. Requests to add more items that
would exceed this limit will fail.

Note that you can only add media items that have been
[uploaded by your application](https://developers.google.com/photos/library/legacy/guides/upload-media.md.txt) to
[albums that your application has
created](https://developers.google.com/photos/library/legacy/guides/manage-albums#creating-new-album). Media items
must also be in the user's library. For albums that are shared, they must either
be [owned by the
user](https://developers.google.com/photos/library/legacy/guides/share-media#sharing-album)
or the user must be a collaborator who has already joined the album.

To add media items to an album, call
[`albums.batchAddMediaItems`](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums/batchAddMediaItems.md.txt)
with the identifiers of the media items and the album.

### REST

Here is a header for a POST request:

```
POST https://photoslibrary.googleapis.com/v1/albums/album-id:batchAddMediaItems
Content-type: application/json
Authorization: Bearer oauth2-token
```

The request body looks like this:

```restructuredtext
{
   "mediaItemIds": [
     "media-item-id",
     "another-media-item-id",
     ...
   ]
}
```

If successful, the response returns an empty JSON response and the HTTP
Success status.

### Java

```java
try {
  // List of media item IDs to add
  List<String> mediaItemIds = Arrays
      .asList("MEDIA_ITEM_ID", "ANOTHER_MEDIA_ITEM_ID");

  // ID of the album to add media items to
  String albumId = "ALBUM_ID";

  // Add all given media items to the album
  photosLibraryClient.batchAddMediaItemsToAlbum(albumId, mediaItemIds);

} catch (ApiException e) {
  // An exception is thrown if the media items could not be added
}
```

### PHP

```php
try {

    // List of media item IDs to add
    $mediaItemIds = ["MEDIA_ITEM_ID", "ANOTHER_MEDIA_ITEM_ID"];

    // ID of the album to add media items to
    $albumId = "ALBUM_ID";

    // Add all given media items to the album
    $response = $photosLibraryClient->batchAddMediaItemsToAlbum($albumId, $mediaItemIds);

} catch (\Google\ApiCore\ApiException $e) {
    // Handle Error
}
```

## Removing media items from an album

You can remove media items that you have added from an album by calling
[`albums.batchRemoveMediaItems`](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums/batchRemoveMediaItems.md.txt).

The entire request will fail if invalid media items are specified. Partial
success is not supported.

Note that you can only remove media items that your application
[has added to an album](https://developers.google.com/photos/library/legacy/guides/manage-albums.md.txt#adding-items-to-album)
or that have been
[created in an album as part of an
upload](https://developers.google.com/photos/library/legacy/guides/upload-media#creating-media-item). For albums
that are shared, you can only remove items added by other collaborators if you
are acting on behalf of [the
owner](https://developers.google.com/photos/library/legacy/guides/share-media#sharing-album)
of the album.

To remove media items from an album, call
[`albums.batchRemoveMediaItems`](https://developers.google.com/photos/library/legacy/reference/rest/v1/albums/batchRemoveMediaItems.md.txt)
with the identifiers of the media items and the album.

### REST

Here is a header for a POST request:

```
POST https://photoslibrary.googleapis.com/v1/albums/album-id:batchRemoveMediaItems
Content-type: application/json
Authorization: Bearer oauth2-token
```

The request body looks like this:

```restructuredtext
{
   "mediaItemIds": [
     "media-item-id",
     "another-media-item-id",
     ...
   ]
}
```

If successful, the response returns an empty JSON response and the HTTP
Success status.

### Java

```java
try {
  // List of media item IDs to remove
  List<String> mediaItemIds = Arrays
      .asList("MEDIA_ITEM_ID", "ANOTHER_MEDIA_ITEM_ID");

  // ID of the album to remove media items from
  String albumId = "ALBUM_ID";

  // Remove all given media items from the album
  photosLibraryClient.batchRemoveMediaItemsFromAlbum(albumId, mediaItemIds);

} catch (ApiException e) {
  // An exception is thrown if the media items could not be removed
}
```

### PHP

```php
try {

    // List of media item IDs to remove
    $mediaItemIds = ["MEDIA_ITEM_ID", "ANOTHER_MEDIA_ITEM_ID"];

    // ID of the album to remove media items from
    $albumId = "ALBUM_ID";

    // Remove all given media items from the album
    $response = $photosLibraryClient->batchRemoveMediaItemsFromAlbum($albumId, $mediaItemIds);

} catch (\Google\ApiCore\ApiException $e) {
    // Handle Error
}
```