This page describes how to make a resumable upload request in the Cloud Storage JSON and XML APIs. This protocol lets you resume an upload operation after a communication failure interrupts the flow of data.
For information on using resumable uploads in the Google Cloud CLI and client libraries, see How tools and APIs use resumable uploads.
Required roles
To get the permissions that you need to perform a resumable upload, ask your administrator to grant you one of the following roles:
For uploads that include an Object Retention Lock, ask your administrator to grant you the Storage Object Admin (
roles/storage.objectAdmin) IAM role for the bucket.For all other cases, ask your administrator to grant you the Storage Object User (
roles/storage.objectUser) IAM role for the bucket.
These predefined roles contain the permissions required to upload an object to a bucket for their respective cases. To see the exact permissions that are required, expand the Required permissions section:
Required permissions
storage.objects.createstorage.objects.delete- This permission is only required for uploads that overwrite an existing object.
storage.objects.setRetention- This permission is only required for uploads that include an Object Retention Lock.
You can also get these permissions with other predefined roles or custom roles.
For information about granting roles on buckets, see Set and manage IAM policies on buckets.
Initiate a resumable upload session
To initiate a resumable upload session:
JSON API
Have gcloud CLI installed and initialized, which lets you generate an access token for the
Authorizationheader.Optionally, create a JSON file that contains the metadata you want to set on the object that you're uploading. For example, the following JSON file sets the
contentTypemetadata of the object you want to upload toimage/png:{ "contentType": "image/png" }Use
cURLto call the JSON API with aPOSTObject request:curl -i -X POST --data-binary @METADATA_LOCATION \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ -H "Content-Length: INITIAL_REQUEST_LENGTH" \ "https://storage.googleapis.com/upload/storage/v1/b/BUCKET_NAME/o?uploadType=resumable&name=OBJECT_NAME"Where:
METADATA_LOCATIONis the local path to the JSON file containing the optional metadata you specified in the previous step. If you are not including a metadata file, exclude this, along with--data-binary @and theContent-Typeheader.INITIAL_REQUEST_LENGTHis the number of bytes in the body of this initial request, for example79.BUCKET_NAMEis the name of the bucket to which you are uploading your object. For example,my-bucket.OBJECT_NAMEis the URL-encoded name you want to give your object. For example,pets/dog.png, URL-encoded aspets%2Fdog.png. This is not required if you included anamein the object metadata file in Step 2.
If you have enabled Cross-Origin Resource Sharing, you should also include an
Originheader in both this and subsequent upload requests.Optional headers that you can add to the request include
X-Upload-Content-TypeandX-Upload-Content-Length.If successful, the response includes a
200status code and looks similar to the following:HTTP/2 200 content-type: text/plain; charset=utf-8 x-guploader-uploadid: ABgVH8_jqDHM_KOvNAJCx73r9v5fINktk9U-pXana1szCM5803tlJ7CKsRbDxkyYCrfEiNqzcZ6B7DfoDtc-bdzpH-SpVTAMEO9EQV34qG0-0yk location: https://storage.googleapis.com/upload/storage/v1/b/my-bucket/o?uploadType=resumable&name=cat-pic.jpeg&upload_id=ABgVH8_jqDHM_KOvNAJCx73r9v5fINktk9U-pXana1szCM5803tlJ7CKsRbDxkyYCrfEiNqzcZ6B7DfoDtc-bdzpH-SpVTAMEO9EQV34qG0-0yk date: Mon, 07 Jul 2025 14:57:21 GMT vary: Origin vary: X-Origin cache-control: no-cache, no-store, max-age=0, must-revalidate expires: Mon, 01 Jan 1990 00:00:00 GMT pragma: no-cache content-length: 0 server: UploadServer alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Save the resumable session URI given in the
locationheader of the response to yourPOSTObject request.This URI is used in subsequent requests to upload the object data.