Skip to content

Instances API Reference

Reference · Updated Sep 2026

Coming from another cloud?

▸AWS·EC2 Instances

EC2 Instanceshigh

  • Uses EC2 RunInstances API instead of Nova servers.create.
  • Requires predefined instance type selection.
  • Supports per-second On-Demand billing and Spot/Reserved options.
  • Includes hibernation state not standard in OpenStack.
AWS docs ↗
▸Azure·Virtual Machines

Virtual Machineshigh

  • Uses Azure Resource Manager (ARM) REST API at /providers/Microsoft.Compute/virtualMachines instead of OpenStack Nova API at /v2.1/servers.
  • Tightly integrated with Azure services like Azure Active Directory for authentication, unlike OpenStack's Keystone.
  • VM creation requires specifying size from predefined series with hardware-specific features (e.g., AMD/Intel/ARM), not custom flavor configs.
  • Billed per second with complex pricing tiers based on series/reservation options, vs OpenStack's typically hourly or usage-based.
Azure docs ↗
▸DigitalOcean·API

DigitalOcean APIhigh

  • Uses REST API over HTTPS with Bearer token authentication via personal access tokens, not OpenStack's Keystone token-based auth.
  • Base URL https://api.digitalocean.com/v2, incompatible with OpenStack APIs like Nova/Neutron.
  • Scoped permissions tied to granular API scopes based on team roles, unlike OpenStack role/project assignments.
  • Rate limits: 5000/hour, 250/minute.
DigitalOcean docs ↗
▸Google Cloud·VM instances

VM instanceshigh

  • Uses REST API 'instances.insert' instead of Nova 'servers.create' with different auth via service accounts vs Keystone.
  • Supports bare metal instances (no hypervisor), not in standard OpenStack Nova.
  • Network interfaces tied to VPC subnets; differs from Neutron ports/floating IPs.
Google Cloud docs ↗
▸Hetzner·Cloud API

Cloud APIhigh

  • Proprietary REST API over HTTPS with Bearer token auth, not OpenStack Identity API (keystone) endpoints or mechanisms.
  • Base URL https://api.hetzner.cloud/v1/ with resource-specific endpoints (e.g., /servers) vs OpenStack service endpoints (nova, cinder).
  • No multi-project handling in single auth; separate per-project tokens vs keystone scopes/projects.
  • Missing identity/catalog endpoints; no service discovery via API.
Hetzner docs ↗

Instances API reference

See the upstream Compute (Nova) API reference.

Quake AI runs the Compute API as Nova v2.1. In these methods, {server_id} is the UUID of the instance and {attachment_id} is the UUID of the volume attachment. Request bodies carry the action payload: start, stop, reboot, resize, snapshot, and volume or floating-IP management.

Service base URLs#

Most endpoints here are Nova (Compute) paths. A few cross into other services: createImage returns a Glance (Image) URL, floating-IP management uses Neutron (Network), and boot-from-volume snapshot cleanup uses Cinder (Block Storage). Prefix each path with the base URL for its service:

ServiceBase URL
Nova (Compute)https://compute.{region}.rumble.cloud/v2.1
Glance (Image)https://image.{region}.rumble.cloud
Neutron (Network)https://network.{region}.rumble.cloud
Cinder (Block Storage)https://volume.{region}.rumble.cloud

Replace {region} with your region. Currently only us-east-1 is available. Discover each endpoint from the service catalog:

bash
openstack catalog show compute
openstack catalog show image
openstack catalog show network
openstack catalog show volume

The examples below write these base URLs as {nova_base}, {glance_base}, {network_base}, and {volume_base}.

List instances#

bash
GET {nova_base}/servers

Response: 200 OK.

Show instance details#

bash
GET {nova_base}/servers/{server_id}

Response: 200 OK. This is the full server object, including addresses, OS-EXT-STS:vm_state, OS-EXT-STS:task_state, flavor, and os-extended-volumes:volumes_attached.

Create an instance#

bash
POST {nova_base}/servers

Every Quake AI flavor has disk=0, so each instance boots from a volume. A create body that sets imageRef directly (boot from local disk) returns 403 Forbidden with Only volume-backed servers are allowed for flavors with zero disk. Omit imageRef and request the root volume with block_device_mapping_v2:

JSON
{
  "server": {
    "name": "Instance Name",
    "flavorRef": "7b3e1c9a-2f4d-4a8e-bc11-9d6f0a2e5c34",
    "networks": [{ "uuid": "3f9c8b27-6e1a-4d52-8c0f-7a2b9e4d1c63" }],
    "block_device_mapping_v2": [
      {
        "boot_index": 0,
        "uuid": "a1d2e3f4-5b6c-47d8-9e0a-1b2c3d4e5f60",
        "source_type": "image",
        "destination_type": "volume",
        "volume_size": 20,
        "delete_on_termination": true
      }
    ]
  }
}

Required fields:

  • flavorRef: flavor UUID.
  • networks[].uuid: network UUID.
  • block_device_mapping_v2[].uuid: image UUID to clone into a new root volume.
  • block_device_mapping_v2[].volume_size: root volume size in GB.
  • block_device_mapping_v2[].delete_on_termination: set true to delete the root volume when the server is deleted.

Response: 202 Accepted. The body is a summary view:

JSON
{
  "server": {
    "id": "2c4e6a80-1b3d-4f5e-9a7c-8d0e2f4a6b18",
    "links": [
      { "rel": "self", "href": "{nova_base}/servers/2c4e6a80-1b3d-4f5e-9a7c-8d0e2f4a6b18" },
      { "rel": "bookmark", "href": "..." }
    ],
    "OS-DCF:diskConfig": "MANUAL",
    "security_groups": [{ "name": "default" }],
    "adminPass": "RANDOM_ROOT_PASSWORD"
  }
}

The create response is a summary. To read the full server object (addresses, host, expanded flavor), follow links.self to GET {nova_base}/servers/{server_id}.

Delete an instance#

bash
DELETE {nova_base}/servers/{server_id}

Response: 204 No Content. The server enters a deleting task state. Poll the show-instance endpoint until it returns 404 itemNotFound.

Start an instance#

bash
POST {nova_base}/servers/{server_id}/action

Request body:

JSON
{ "os-start": null }

Response: 202 Accepted. Poll until status is ACTIVE.

Stop an instance#

bash
POST {nova_base}/servers/{server_id}/action

Request body:

JSON
{ "os-stop": null }

Response: 202 Accepted. Poll until status is SHUTOFF.

Reboot an instance#

bash
POST {nova_base}/servers/{server_id}/action

Request body. type must be exactly "HARD" (forced power cycle) or "SOFT" (graceful guest reboot through ACPI); any other value returns 400 Bad Request.

Hard reboot:

JSON
{ "reboot": { "type": "HARD" } }

Soft reboot:

JSON
{ "reboot": { "type": "SOFT" } }

Response: 202 Accepted.

Resize an instance#

bash
POST {nova_base}/servers/{server_id}/action

Request body. flavorRef must be a different flavor UUID; resizing to the current flavor returns 400 Bad Request with When resizing, instances must change flavor!.

JSON
{ "resize": { "flavorRef": "4d8a1f60-2c3b-4e7a-9f15-6b0d8c2e3a91" } }

Response: 202 Accepted. The server moves through RESIZE to VERIFY_RESIZE, then waits for you to confirm or revert.

Confirm resize#

bash
POST {nova_base}/servers/{server_id}/action

Request body:

JSON
{ "confirmResize": null }

Response: 204 No Content. Call this only once status is VERIFY_RESIZE; calling it earlier returns 409 conflictingRequest.

Revert resize#

bash
POST {nova_base}/servers/{server_id}/action

Request body:

JSON
{ "revertResize": null }

Response: 202 Accepted. Call this only once status is VERIFY_RESIZE.

Create an image snapshot of an instance#

bash
POST {nova_base}/servers/{server_id}/action

Request body:

JSON
{ "createImage": { "name": "Snapshot Name" } }

Response: 202 Accepted with an empty body. The new image's ID is returned in the Location response header, not the body:

HTTP/2 202
Location: https://IMAGE_HOST/images/d4c3b2a1-6f5e-4d3c-b2a1-0f9e8d7c6b5a
Content-Length: 0

Attach a volume to an instance#

bash
POST {nova_base}/servers/{server_id}/os-volume_attachments

Request body:

JSON
{ "volumeAttachment": { "volumeId": "9e8d7c6b-5a4f-43e2-91d0-0c1b2a3d4e5f" } }

Response: 200 OK.

JSON
{
  "volumeAttachment": {
    "id": "9e8d7c6b-5a4f-43e2-91d0-0c1b2a3d4e5f",
    "serverId": "2c4e6a80-1b3d-4f5e-9a7c-8d0e2f4a6b18",
    "volumeId": "9e8d7c6b-5a4f-43e2-91d0-0c1b2a3d4e5f",
    "device": "/dev/sdb"
  }
}

Detach a volume from an instance#

bash
DELETE {nova_base}/servers/{server_id}/os-volume_attachments/{attachment_id}

Response: 202 Accepted with an empty body.

Associate a floating IP with an instance#

To associate a floating IP with a server, find the server's port, then PUT to the Neutron floating IP:

bash
# 1. Find the server's port_id.
GET {network_base}/v2.0/ports?device_id={server_id}

# 2. Allocate a floating IP (skip if you are reusing one).
POST {network_base}/v2.0/floatingips
# { "floatingip": { "floating_network_id": "6d5c4b3a-2f1e-4098-87a6-b5c4d3e2f1a0" } }

# 3. Associate it with the port.
PUT {network_base}/v2.0/floatingips/{fip_id}
# { "floatingip": { "port_id": "1f2e3d4c-5b6a-4978-8c0d-1e2f3a4b5c6d" } }

Disassociate a floating IP from an instance#

bash
PUT {network_base}/v2.0/floatingips/{fip_id}
# { "floatingip": { "port_id": null } }

Find {network_base} with openstack catalog show network. The Neutron floating-IP request and response schema is documented on the Network API reference.

Response codes and error envelopes#

Nova returns structured JSON error envelopes. (Glance, the Image service, returns HTML instead.) For the full status-code catalog with resolution steps, see the Compute API error reference.

Success codes by endpoint:

EndpointStatus
GET {nova_base}/servers200
GET {nova_base}/servers/{server_id}200
POST {nova_base}/servers202
DELETE {nova_base}/servers/{server_id}204
POST {nova_base}/servers/{server_id}/action (os-start, os-stop, reboot, resize, revertResize, createImage)202
POST {nova_base}/servers/{server_id}/action (confirmResize)204
POST {nova_base}/servers/{server_id}/os-volume_attachments200
DELETE {nova_base}/servers/{server_id}/os-volume_attachments/{attachment_id}202

Error envelopes are JSON, keyed by error class:

CodeEnvelope keyMeaning
400badRequestMalformed request, missing fields, or a no-op resize
401unauthorizedMissing or expired X-Auth-Token
403forbiddenRole lacks permission, or a zero-disk flavor without block_device_mapping_v2
404itemNotFoundServer, volume, or flavor UUID not found
409conflictingRequestServer is in the wrong vm_state or task_state for the action

Example 409 envelope:

JSON
{
  "conflictingRequest": {
    "code": 409,
    "message": "Cannot 'resize' instance while it is in task_state reboot_started_hard"
  }
}

Actions on /action are asynchronous: a 202 means the request was accepted, not that it finished. Poll GET {nova_base}/servers/{server_id} and check both status and OS-EXT-STS:task_state before the next action. Common 409 conflictingRequest cases:

  • Cannot 'ACTION' instance ... while it is in task_state ...: the previous action is still running. Wait until status is ACTIVE and OS-EXT-STS:task_state is None.
  • Cannot 'confirmResize' instance ... while it is in vm_state active: the server has not reached VERIFY_RESIZE yet. Wait until status is VERIFY_RESIZE before calling confirmResize or revertResize.

Status and task_state#

statusOS-EXT-STS:task_stateMeaning
BUILDscheduling, spawningInstance is being created
ACTIVENoneRunning and idle
ACTIVEnon-NoneAn action is in flight
SHUTOFFNonePowered off
HARD_REBOOTreboot_started_hardHard reboot in progress
RESIZEresize_migratingMigrating to the new flavor
VERIFY_RESIZENoneWaiting for confirmResize or revertResize
ERRORNoneBuild or migration failed; read the fault field
DELETEDn/aDeleted; GET returns 404

Quick answers

Was this page helpful?