Creating API requests and handling responses Stay organized with collections Save and categorize content based on your preferences.
This document describes how to construct API requests and handleAPI responses from the Compute Engine API. It covers how to:
- Construct a request body.
- Determine the resource URIs necessary for a request.
- Handle API responses.
- Determine whether an API request succeeded.
This document does not cover how to authenticate to the API. To learn how toauthenticate to the API, readAuthenticate to Compute Engine.
Before you begin
- Get familiar withREST APIs.
- Know how toauthenticateto the Compute Engine API.
Creating an API request
The Compute Engine API expects API requests to be in JSON format.To make an API request, you can either make a direct HTTP request, by usingtools likecurl orhttplib2, or you can use one of theavailable client libraries.
When you make an API request that requires a request body, like aPOST,UPDATE, orPATCH request, the request body contains resource propertiesthat you want to set in this request. For example, the followingcurl commandmakes aPOST request to the Instances resource URI. The request creates aninstance with the properties defined in the request body. The request body isindicated by the-d flag:
curl -X POST -H "Authorization: Bearer [OAUTH_TOKEN]" -H "Content-Type: application/json" \https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances -d \'{ "disks":[ { "boot":"true", "initializeParams":{ "sourceImage":"https://www.googleapis.com/compute/v1/projects/debian-cloud/global/images/debian-10-buster-v20210122" } } ], "machineType":"https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/machineTypes/e2-standard-2", "name":"VM_NAME", "networkInterfaces":[ { "accessConfigs":[ { "name":"external-nat", "type":"ONE_TO_ONE_NAT" } ], "network":"https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/networks/default" } ]}'The image URI has a different project ID (debian-cloud) from your project IDbecause images belong to different projects, depending on the type of image.For example, all publicly available Debian images offered byCompute Engine are hosted on thedebian-cloud project.
When referencing another resource, use the fully qualified resource URI.For example, thenetwork property uses a fully qualified URI to thedefault network.
Example API requests
Python
defcreate_instance(compute:object,project:str,zone:str,name:str,bucket:str,)->str:"""Creates an instance in the specified zone. Args: compute: an initialized compute service object. project: the Google Cloud project ID. zone: the name of the zone in which the instances should be created. name: the name of the instance. bucket: the name of the bucket in which the image should be written. Returns: The instance object. """# Get the latest Debian Jessie image.image_response=(compute.images().getFromFamily(project="debian-cloud",family="debian-11").execute())source_disk_image=image_response["selfLink"]# Configure the machinemachine_type="zones/%s/machineTypes/n1-standard-1"%zonestartup_script=open(os.path.join(os.path.dirname(__file__),"startup-script.sh")).read()image_url="http://storage.googleapis.com/gce-demo-input/photo.jpg"image_caption="Ready for dessert?"config={"name":name,"machineType":machine_type,# Specify the boot disk and the image to use as a source."disks":[{"boot":True,"autoDelete":True,"initializeParams":{"sourceImage":source_disk_image,},}],# Specify a network interface with NAT to access the public# internet."networkInterfaces":[{"network":"global/networks/default","accessConfigs":[{"type":"ONE_TO_ONE_NAT","name":"External NAT"}],}],# Allow the instance to access cloud storage and logging."serviceAccounts":[{"email":"default","scopes":["https://www.googleapis.com/auth/devstorage.read_write","https://www.googleapis.com/auth/logging.write",],}],# Metadata is readable from the instance and allows you to# pass configuration from deployment scripts to instances."metadata":{"items":[{# Startup script is automatically executed by the# instance upon startup."key":"startup-script","value":startup_script,},{"key":"url","value":image_url},{"key":"text","value":image_caption},{"key":"bucket","value":bucket},]},}returncompute.instances().insert(project=project,zone=zone,body=config).execute()Java
publicstaticOperationstartInstance(Computecompute,StringinstanceName)throwsIOException{System.out.println("================== Starting New Instance ==================");// Create VM Instance object with the required properties.Instanceinstance=newInstance();instance.setName(instanceName);instance.setMachineType(String.format("https://www.googleapis.com/compute/v1/projects/%s/zones/%s/machineTypes/e2-standard-1",PROJECT_ID,ZONE_NAME));// Add Network Interface to be used by VM Instance.NetworkInterfaceifc=newNetworkInterface();ifc.setNetwork(String.format("https://www.googleapis.com/compute/v1/projects/%s/global/networks/default",PROJECT_ID));List<AccessConfig>configs=newArrayList<>();AccessConfigconfig=newAccessConfig();config.setType(NETWORK_INTERFACE_CONFIG);config.setName(NETWORK_ACCESS_CONFIG);configs.add(config);ifc.setAccessConfigs(configs);instance.setNetworkInterfaces(Collections.singletonList(ifc));// Add attached Persistent Disk to be used by VM Instance.AttachedDiskdisk=newAttachedDisk();disk.setBoot(true);disk.setAutoDelete(true);disk.setType("PERSISTENT");AttachedDiskInitializeParamsparams=newAttachedDiskInitializeParams();// Assign the Persistent Disk the same name as the VM Instance.params.setDiskName(instanceName);// Specify the source operating system machine image to be used by the VM Instance.params.setSourceImage(SOURCE_IMAGE_PREFIX+SOURCE_IMAGE_PATH);// Specify the disk type as Standard Persistent Diskparams.setDiskType(String.format("https://www.googleapis.com/compute/v1/projects/%s/zones/%s/diskTypes/pd-standard",PROJECT_ID,ZONE_NAME));disk.setInitializeParams(params);instance.setDisks(Collections.singletonList(disk));// Initialize the service account to be used by the VM Instance and set the API access scopes.ServiceAccountaccount=newServiceAccount();account.setEmail("default");List<String>scopes=newArrayList<>();scopes.add("https://www.googleapis.com/auth/devstorage.full_control");scopes.add("https://www.googleapis.com/auth/compute");account.setScopes(scopes);instance.setServiceAccounts(Collections.singletonList(account));// Optional - Add a startup script to be used by the VM Instance.Metadatameta=newMetadata();Metadata.Itemsitem=newMetadata.Items();item.setKey("startup-script-url");// If you put a script called "vm-startup.sh" in this Google Cloud Storage// bucket, it will execute on VM startup. This assumes you've created a// bucket named the same as your PROJECT_ID.// For info on creating buckets see:// https://cloud.google.com/storage/docs/cloud-console#_creatingbucketsitem.setValue(String.format("gs://%s/vm-startup.sh",PROJECT_ID));meta.setItems(Collections.singletonList(item));instance.setMetadata(meta);System.out.println(instance.toPrettyString());Compute.Instances.Insertinsert=compute.instances().insert(PROJECT_ID,ZONE_NAME,instance);returninsert.execute();}Creating resource URIs
In Compute Engine API, a reference to another Google Cloud resource is givenas a fully qualified URI:
https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/RESOURCE_TYPE/SPECIFIC_RESOURCE
Whenever you specify an image, a machine type, a network, or any other resource,you must provide the URI to the resource when using the API. Client tools likethe Google Cloud CLI and the Google Cloud console hide this complexity and handlecreating these resource URIs for you, but when interacting with the APIdirectly, you must create these resource URIs yourself.
There are slightly different resource URIs for different types of resources. Forexample, a zonal resource has thezone specification in the URI:
https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/machineTypes/e2-standard-2
Regional resources replace thezone specification with aregionspecification:
https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/REGION/addresses/ADDRESS_NAME
Similarly, global resources have theglobal specification:
https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/images/VM_NAME
The Compute Engine API also accepts partial URIs because the service caninfer information like the project ID. So, the following partial versions of theearlier URIs are also acceptable:
zones/ZONE/machineTypes/e2-standard-2
regions/REGION/addresses/ADDRESS_NAME
project/PROJECT_ID/global/images/VM_NAME
In the partial URIs, both the zonal and regional URIs omitted the projectID but the image URI did not. This is because publicly available images offeredby Compute Engine are hosted in other projects, likedebian-cloud forall Debian images andubuntu-os-cloud for all Ubuntu images. Before you canuse these images, you need to provide the appropriate project ID. If you omitthe project ID for images, Compute Engine attempts to find the image inyour project, and the request fails because the image doesn't exist.
However, if you use acustom imagethat belongs to your project (the same project you are creating this resourcein), you can omit the project specification when providing an image URI.
Determining required properties
The Compute Engine API reference documentation, available for bothv1andbeta APIs, describes all of the possibleproperties you can set for a specific resource. The reference documentationmakes a distinction between mutable versus immutable properties(marked by an[Output Only] in the property description), but to determinerequired properties for a resource, you need to review the documentationspecific to that task.
For example, if you are creating an instance, read theCreating an instance from an imagedocumentation to see the API properties required for the request. If youwant to create a static external IP address in the API, read theStatic external IP addressesdocumentation.
Validating API requests
To validate your API requests:
- In theCompute Engine API reference,find the method your code is calling. For example,
v1/compute.instances.insert. From the contents menu, clickTry it! This opens theTry this APIwindow.

UnderRequest parameters, you don't need to provide aproject orzone because validation doesn't require submitting the request.
UnderRequest body, paste your request.

Malformed elements of the request are underlined in blue. Click eachunderlined section for more information about the issue to be addressed.
Handling API responses
If you make a request that mutates (alters) data, Compute Enginereturns anOperation object that you can then poll to get the status ofthe operations for your request. TheOperation resource looks like this:
{ "kind": "compute#operation", "id": "7127550864823803662", "name": "operation-1458856416788-52ed27a803e22-1c3bd86a-9e95017b", "zone": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE", "operationType": "insert", "targetLink": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/EXAMPLE_VM", "targetId": "4132355614508179214", "status": "PENDING", "user": "user@example.com", "progress": 0, "insertTime": "2016-03-24T14:53:37.788-07:00", "selfLink": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/operations/operation-1458856416788-52ed27a803e22-1c3bd86a-9e95017b"}If the original request is to mutate (alter) a zonal resource–for example, tosnapshot a disk or to stop an instance–Compute Engine returns azoneOperationsobject. Similarly, regional and global resources return aregionOperationsorglobalOperationsobject, respectively. You can get the status of an operation by performing arequest that uses theget orwait method for the specificOperation resource and providing thename of the operation.
Your request is not complete until theOperation resource's status returns asDONE. This can take some time depending on the nature of your request. Then,after theOperation resource's status returns asDONE, you can check to seeif the operation succeeded and whether there were any errors.
For example, the following response indicates that the preceding operationis now complete, specified by theDONE status:
endTime: '2016-03-24T14:54:07.119-07:00'id: '7127550864823803662'insertTime: '2016-03-24T14:53:37.788-07:00'kind: compute#operationname: operation-1458856416788-52ed27a803e22-1c3bd86a-9e95017boperationType: insertprogress: 100selfLink: https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/operations/operation-1458856416788-52ed27a803e22-1c3bd86a-9e95017bstartTime: '2016-03-24T14:53:38.397-07:00'status: DONEtargetId: '4132355614508179214'targetLink: https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/EXAMPLE_VMuser: user@example.comzone: https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE
To confirm, make aget request to the resource to check that it exists andis running. For example:
GET /compute/v1/projects/PROJECT_ID/zones/ZONE/instances/EXAMPLE_VM{ "cpuPlatform": "Intel Haswell", "creationTimestamp": "2016-03-24T14:53:37.170-07:00", "disks": [ ..[snip].. "selfLink": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE/instances/EXAMPLE_VM", "status": "RUNNING", "tags": { "fingerprint": "42WmSpB8rSM=" }, "zone": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/ZONE"}Polling operations
You can write some code to periodically poll the operation with agetorwait request that returns when the operation status isDONE.
With aget request, the operation is returned immediately, regardless of thestatus of the operation. You need to poll the operation periodically to knowwhen the operation is done.
If you make await request, the request returns when the operation isDONEor if the request is approaching the 2 minute deadline. You can choose to usewait orget to poll your operations, but thewait method providescertain benefits over theget method:
- You can set up your clients to poll for the operation status less frequently,reducing your QPS usage of the Compute Engine API.
- The average latency between when the operation is done and when the client isinformed that the operation is done is significantly reduced because theserver responds as soon as the operation is done.
- The method provides bounded waits. The method waits for no more than thedefault HTTP timeout (2 minutes) and then returns the current state of theoperation, which might be
DONEor still in progress.
Thewait method is abest-effort API. If the server is overloaded, therequest might return before it reaches the default deadline, or after waitingjust zero seconds. The method is also not guaranteed to return only when theoperation isDONE. For example, if the request approaches the 2 minutedeadline, the method returns even if the operation is not done. To checkon your operations, we recommend that you use either thewait orget method—in a retry loop with sleep in-between—to periodicallypoll the operation status. The maximum retry interval shouldn't exceedtheminimum operation retention period.
Example polling
The following examples use theget method. You can replace theget methodwith thewait method:
Python
defwait_for_operation(compute:object,project:str,zone:str,operation:str,)->dict:"""Waits for the given operation to complete. Args: compute: an initialized compute service object. project: the Google Cloud project ID. zone: the name of the zone in which the operation should be executed. operation: the operation ID. Returns: The result of the operation. """print("Waiting for operation to finish...")whileTrue:result=(compute.zoneOperations().get(project=project,zone=zone,operation=operation).execute())ifresult["status"]=="DONE":print("done.")if"error"inresult:raiseException(result["error"])returnresulttime.sleep(1)Java
/** * Wait until {@code operation} is completed. * * @param compute the {@code Compute} object * @param operation the operation returned by the original request * @param timeout the timeout, in millis * @return the error, if any, else {@code null} if there was no error * @throws InterruptedException if we timed out waiting for the operation to complete * @throws IOException if we had trouble connecting */publicstaticOperation.ErrorblockUntilComplete(Computecompute,Operationoperation,longtimeout)throwsException{longstart=System.currentTimeMillis();finallongpollInterval=5*1000;Stringzone=getLastWordFromUrl(operation.getZone());// null for global/regional operationsStringregion=getLastWordFromUrl(operation.getRegion());Stringstatus=operation.getStatus();StringopId=operation.getName();while(operation!=null &&!status.equals("DONE")){Thread.sleep(pollInterval);longelapsed=System.currentTimeMillis()-start;if(elapsed>=timeout){thrownewInterruptedException("Timed out waiting for operation to complete");}System.out.println("waiting...");if(zone!=null){Compute.ZoneOperations.Getget=compute.zoneOperations().get(PROJECT_ID,zone,opId);operation=get.execute();}elseif(region!=null){Compute.RegionOperations.Getget=compute.regionOperations().get(PROJECT_ID,region,opId);operation=get.execute();}else{Compute.GlobalOperations.Getget=compute.globalOperations().get(PROJECT_ID,opId);operation=get.execute();}if(operation!=null){status=operation.getStatus();}}returnoperation==null?null:operation.getError();}Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-12-15 UTC.