Uploading media items is a two-step process:
- Upload the bytes of your media files to a Google Server using the uploads endpoint. This returns an upload token which identifies the uploaded bytes.
- Use a batchCreate call with the upload token to create a media item in the user's Google Photos account.
These steps outline the process of uploading a single media item. If you are uploading multiple media items (very likely for any production application), review the best practices for uploads to improve your upload efficiency.
Before you begin
Required authorization scopes
Uploading media items to a user's library or album requires the
photoslibrary.appendonly
scope. For more information on scopes, see
Authorization scopes.
Accepted file types and sizes
You can upload the file types listed in this table.
Media type | Accepted file types | Maximum file size |
---|---|---|
Photos | AVIF, BMP, GIF, HEIC, ICO, JPG, PNG, TIFF, WEBP, some RAW files. | 200 MB |
Videos | 3GP, 3G2, ASF, AVI, DIVX, M2T, M2TS, M4V, MKV, MMV, MOD, MOV, MP4, MPG, MTS, TOD, WMV. | 20 GB |
Step 1: Uploading bytes
Upload bytes to Google using upload requests. A successful upload request
returns an upload token in the form of a raw text string. Use these upload
tokens to create media items with the batchCreate
call.
REST
Include the following fields in the POST request header:
Header fields | |
---|---|
Content-type |
Set to application/octet-stream . |
X-Goog-Upload-Content-Type |
Recommended. Set to the MIME type of the bytes you're uploading.
Common MIME types include image/jpeg ,
image/png , and image/gif .
|
X-Goog-Upload-Protocol |
Set to raw . |
Here is a POST request header:
POST https://photoslibrary.googleapis.com/v1/uploads Authorization: Bearer oauth2-token Content-type: application/octet-stream X-Goog-Upload-Content-Type: mime-type X-Goog-Upload-Protocol: raw
In the request body, include the binary of the file:
media-binary-data
If this POST request is successful, an upload token which is in the form
of a raw text string, is returned as the response body. To create media
items, use these text strings in the batchCreate
call.
upload-token
The suggested file size for images is less than 50 MB. Files larger than 50 MB are prone to performance issues.
The Google Photos Library API supports resumable uploads. A resumable upload lets you split a media file into multiple sections and upload one section at a time.
Step 2: Creating a media item
After uploading the bytes of your media files, you can create them as media items in Google Photos using upload tokens. An upload token is valid for one day after being created. A media item is always added to the user's library. Media items can only be added to albums created by your app. For more information, see Authorization scopes.
To create new media items, call
mediaItems.batchCreate
by specifying a list of newMediaItems
. Each newMediaItem
contains an upload
token that's specified inside a simpleMediaItem
, and an optional description
that is shown to the user.
The description field is restricted to 1000 characters and should only include meaningful text created by users. For example, "Our trip to the park" or "Holiday dinner". Do not include metadata such as filenames, programmatic tags, or other automatically generated text.
For best performance, reduce the number of calls to mediaItems.batchCreate
you
have to make by including multiple media items in one call. Always wait until
the previous request has completed before making a subsequent call for the same
user.
You can create a single media item or multiple media items in a user’s library by specifying the descriptions and corresponding upload tokens:
REST
Here is the POST request header:
POST https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate Content-type: application/json Authorization: Bearer oauth2-token
The request body should specify a list of newMediaItems
.
{ "newMediaItems": [ { "description": "item-description", "simpleMediaItem": { "fileName": "filename", "uploadToken": "upload-token" } } , ... ] }
You can also specify albumId
and albumPosition
to
insert media items at a specific location in the album.
REST
{ "albumId": "album-id", "newMediaItems": [ { "description": "item-description", "simpleMediaItem": { "fileName": "filename", "uploadToken": "upload-token" } } , ... ], "albumPosition": { "position": "after-media-item", "relativeMediaItemId": "media-item-id" } }
For more details regarding positioning in albums, see Add enrichments.
Item creation response
The mediaItems.batchCreate
call returns the result for each of the media items
you tried to create. The list of newMediaItemResults
indicates the status and
includes the uploadToken
for the request. A non-zero status code indicates an
error.
REST
If all media items have been successfully created, the request returns
HTTP status 200 OK
. If some media items can't be created,
the request returns HTTP status 207 MULTI-STATUS
to indicate
partial success.
{ "newMediaItemResults": [ { "uploadToken": "upload-token", "status": { "message": "Success" }, "mediaItem": { "id": "media-item-id", "description": "item-description", "productUrl": "https://photos.google.com/photo/photo-path", "mimeType": "mime-type", "mediaMetadata": { "width": "media-width-in-px", "height": "media-height-in-px", "creationTime": "creation-time", "photo": {} }, "filename": "filename" } }, { "uploadToken": "upload-token", "status": { "code": 13, "message": "Internal error" } } ] }
If an item is successfully added, a mediaItem
is returned that contains its
mediaItemId
, productUrl
and mediaMetadata
. For more information, see
Access media items.
If the media item is a video, it must be processed first. The mediaItem
contains a status
inside its mediaMetadata
that describes the processing
state of the video file. A newly uploaded file returns the PROCESSING
status
first, before it is READY
for use. For details, see Access media
items.
If you encounter an error during this call, follow the Best practices and retry your request. You may want to keep track of successful additions, so the image can be inserted into the album at the correct position during the next request. For more information, see Create albums.
Results are always returned in the same order in which upload tokens were submitted.
Best practices for uploads
The following best practices and resources help improve your overall efficiency with uploads:
- Follow the retry and error handling best
practices, keeping
the following points in mind:
429
errors can occur when your quota has been exausted or you are rate limited for making too many calls too quickly. Make sure you do not callbatchCreate
for the same user until the previous request has completed.429
errors require a minimum30s
delay before retrying. Use an exponential backoff strategy when retrying requests.500
errors occur when the server encounters an error. When uploading, this is most likely because of making multiple write calls (such asbatchCreate
) for the same user at the same time. Check the details of your request and do not make calls tobatchCreate
in parallel.
- Use the resumable upload flow to make your uploads more robust in the case of network interruptions, reducing bandwidth usage by allowing you to resume partically completed uploads. This is important when uploading from client mobile devices, or when uploading large files.
As well, consider the following tips for each step of the upload process: uploading bytes and then creating media items.
Uploading bytes
- Uploading bytes (to retrieve upload tokens) can be done in parallel.
- Always set the correct MIME type in the
X-Goog-Upload-Content-Type
header for each upload call.
Creating media items
Don'fot make calls in parallel to
batchCreate
for a single user.- For each user, make calls to
batchCreate
one after another (in serial). - For multiple users, always make
batchCreate
calls for each user one after another. Only make calls for different users in parallel.
- For each user, make calls to
Include as many
NewMediaItems
as possible in each call tobatchCreate
to minimize the total number of calls you have to make. At most you can include 50 items.Set a meaningful description text that has been created by your users. Do not include metadata such as filenames, programmatic tags, or other automatically generated text in the description field.
Example walkthrough
This example uses pseudocode to walk through uploading media items for multiple users. The goal is to outline both steps of the upload process (uploading raw bytes and creating media items) and detail the best practices for building an efficient and resilient upload integration.
Step 1: Upload raw bytes
First create a queue to upload the raw bytes for your media items from all your
users. Track each returned uploadToken
per user. Remember these key points:
- The number of simultaneous upload threads depends on your operating environment.
- Consider reordering the upload queue as needed. For example, you could prioritize uploads based on the number of remaining uploads per user, a user's overall progress, or other requirements.
Pseudocode
CREATE uploadQueue FROM users, filesToUpload // Upload media bytes in parallel. START multiple THREADS WHILE uploadQueue is not empty POP uploadQueue UPLOAD file for user GET uploadToken CHECK and HANDLE errors STORE uploadToken for user in uploadTokensQueue END
Step 2: Create media items
In step 1, you can upload multiple bytes from multiple users in parallel, but in step 2 step you can only make a single call for each user at a time.
Pseudocode
// For each user, create media items once 50 upload tokens have been // saved, or no more uploads are left per user. WHEN uploadTokensQueue for user is >= 50 OR no more pending uploads for user // Calls can be made in parallel for different users, // but only make a single call per user at a time. START new thread for (this) user if there is no thread yet POP 50 uploadTokens from uploadTokensQueue for user CALL mediaItems.batchCreate with uploadTokens WAIT UNTIL batchCreate call has completed CHECK and HANDLE errors (retry as needed) DONE.
Continue this process until all uploads and media creation calls have completed.