This page describes how to make a resumable upload request to the Google Photos Library API via the REST protocol. This protocol allows you to resume an upload operation after a communication failure interrupts the flow of data.
Use the resumable upload option if:
- You are uploading large files.
- The likelihood of network interruption or some other transmission failure is high (for example, if you are uploading a file from a mobile app).
Resumable uploads can also reduce your bandwidth usage when there is a network failure, because you don't have to restart large file uploads from the beginning.
Step 1: Initiating an upload session
Initiate a resumable upload session by sending a POST request to
https://photoslibrary.googleapis.com/v1/uploads
. Using the resumable upload
URL returned in this request, upload the file.
The POST request must include the following headers:
Header fields | |
---|---|
Content-Length |
Set to 0 as the request body is empty. |
X-Goog-Upload-Command |
Set to start . |
X-Goog-Upload-Content-Type |
Set to the mime type of the file, for example,
image/jpeg . |
X-Goog-Upload-Protocol |
Set to resumable . |
X-Goog-Upload-Raw-Size |
Set to the total number of bytes of the file data to be transferred. |
Here is a POST request header:
POST https://photoslibrary.googleapis.com/v1/uploads Authorization: Bearer oauth2-token Content-Length: 0 X-Goog-Upload-Command: start X-Goog-Upload-Content-Type: mime-type X-Goog-Upload-Protocol: resumable X-Goog-Upload-Raw-Size: bytes-of-file
Step 2: Saving the session URL
If successful, the POST request returns a 200 OK
HTTP status code, including
the following header.
X-Goog-Upload-URL: url-to-make-uploads-to X-Goog-Upload-Chunk-Granularity: chunk-granularity-in-bytes
The header field x-goog-upload-chunk-granularity
contains the byte alignment
and size granularity for all data chunks sent by the client. If the upload is
done in multiple chunks, all uploads, except the last upload,
must be done in multiples of this value. That is, the upload bytes of the file
must be aligned to this value. In the last chunk, you can upload the remaining
bytes.
The header field X-Goog-Upload-URL
contains a unique URL that must be used to
complete the upload through all of the remaining requests. Copy and save this
resumable session URL, so that you can use it for subsequent requests.
Step 3: Uploading the file
There are two ways to upload a file with a resumable session:
- In a single request. This approach is usually the best, because it requires fewer requests, and thus has better performance.
-
In multiple chunks. In this approach, uploads are made in multiple requests by chunking the data. The data is chunked in multiples of
x-goog-upload-chunk-granularity
. If necessary, the chunked requests can be re-tried.Use this approach if:
- You need to reduce the amount of data transferred in any single request. You might need to do this when there is a fixed time limit for individual requests.
- You need to provide a customized indicator showing the upload progress.
- You need to know when it is safe to discard data.
Single Request
To upload the file in a single request:
- Create a
POST
request to the resumable session URL. - Add the file's data to the request body.
Add the following HTTP headers:
Content-Length
: Set to the number of bytes in the file.X-Goog-Upload-Command
: Set toupload, finalize
.
Send the request.
If the upload request is interrupted or you receive a 5xx
response, follow the procedure in Resuming an
interrupted upload.
If the request succeeds, you receive a 200 OK
HTTP status
code and an upload token in the response body.
Create
the media item using this upload token.
Multiple Chunks
To upload the file in multiple chunks:
- Create a
POST
request to the resumable session URL. -
Add the chunk's data to the request body.
Except for the final chunk that completes the upload, create the other chunks in multiples of the accepted size of chunks. Keep the chunk size as large as possible so that the upload is efficient.
-
Add the following HTTP headers:
Content-Length
: Set to the number of bytes in the chunk.X-Goog-Upload-Command
: Set toupload
. For the last chunk, set toupload, finalize
.X-Goog-Upload-Offset
: Set to the offset at which the bytes should be written. Note that the bytes must be uploaded serially. The first offset is0
.
- Send the request.
If the upload request is interrupted or you receive a
5xx
response, follow the procedure in Resuming an interrupted upload. - Repeat these steps for each remaining chunk in the file.
If the request succeeds, you receive a 200 OK
HTTP status
code and an upload token in the response body.
Create
the media item using this upload token.
Example
Single Request
The following example shows a resumable request to upload a 3,039,417-byte JPEG file in a single request.
POST https://photoslibrary.googleapis.com/v1/uploads HTTP/1.1 Content-Length: 0 X-Goog-Upload-Command: start X-Goog-Upload-Content-Type: image/jpeg X-Goog-Upload-Protocol: resumable X-Goog-Upload-Raw-Size: 3039417 [no body]
The response contains the upload URL and the expected chunk size:
HTTP/1.1 200 OK X-Goog-Upload-URL: https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable X-Goog-Upload-Chunk-Granularity: 262144
The final upload request:
POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1 Content-Length: 3039417 X-Goog-Upload-Command: upload, finalize X-Goog-Upload-Offset: 0 [BYTES 0-4199999]
Multiple Chunks
The following example shows a resumable request to upload a
3,039,417-byte JPEG file in multiple chunks, using the resumable session
URL and the accepted chunk size granularity obtained in the previous step.
This example uses a chunk size of 262,144 bytes which was returned in the
header field, x-goog-upload-chunk-granularity
, when the
upload session was initialized. Note that each upload contains bytes that
are in multiples of 262,144.
Initialize the upload session to receive the upload URL and chunk size as described in the previous step:
POST https://photoslibrary.googleapis.com/v1/uploads HTTP/1.1 Content-Length: 0 X-Goog-Upload-Command: start X-Goog-Upload-Content-Type: image/jpeg X-Goog-Upload-Protocol: resumable X-Goog-Upload-Raw-Size: 3039417 [no body]
The response contains the upload URL and the expected chunk size:
HTTP/1.1 200 OK X-Goog-Upload-URL: https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable X-Goog-Upload-Chunk-Granularity: 262144
First chunk:
POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1 Content-Length: 1048576 X-Goog-Upload-Command: upload X-Goog-Upload-Offset: 0 [BYTES 0-1048575]
Second chunk:
POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1 Content-Length: 1048576 X-Goog-Upload-Command: upload X-Goog-Upload-Offset: 1048576 [BYTES 1048576-2097151]
Last chunk:
POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1 Content-Length: 942265 X-Goog-Upload-Command: upload, finalize X-Goog-Upload-Offset: 2097152 [BYTES 2097152-4200000]
Resuming an interrupted upload
If the upload request is interrupted or if you receive a non-200
HTTP status
code, query the server to find out how much of the upload succeeded.
Here is a POST
request to the resumable session URL. X-Goog-Upload-Command
should be set to query
.
POST https://photoslibrary.googleapis.com/v1/uploads?upload_id=AEnB2Urq&upload_protocol=resumable HTTP/1.1 Content-Length: 0 X-Goog-Upload-Command: query
The response from the server includes a 200 OK
HTTP status code and the
current size of the upload.
HTTP/1.1 200 OK X-Goog-Upload-Status: active X-Goog-Upload-Size-Received: 100
You can then resume uploading at this offset. You must resume at the offset provided by the server unless you send a combined upload and finalize command, in which case you can also resume at offset 0.
If the X-Goog-Upload-Status
header in the HTTP response of your query command
is present and the value is not active
, that indicates that the upload has
already been terminated.