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:
| Service | Base 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:
openstack catalog show compute
openstack catalog show image
openstack catalog show network
openstack catalog show volumeThe examples below write these base URLs as {nova_base}, {glance_base}, {network_base}, and {volume_base}.
List instances#
GET {nova_base}/serversResponse: 200 OK.
Show instance details#
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#
POST {nova_base}/serversEvery 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:
{
"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: settrueto delete the root volume when the server is deleted.
Response: 202 Accepted. The body is a summary view:
{
"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#
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#
POST {nova_base}/servers/{server_id}/actionRequest body:
{ "os-start": null }Response: 202 Accepted. Poll until status is ACTIVE.
Stop an instance#
POST {nova_base}/servers/{server_id}/actionRequest body:
{ "os-stop": null }Response: 202 Accepted. Poll until status is SHUTOFF.
Reboot an instance#
POST {nova_base}/servers/{server_id}/actionRequest 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:
{ "reboot": { "type": "HARD" } }Soft reboot:
{ "reboot": { "type": "SOFT" } }Response: 202 Accepted.
Resize an instance#
POST {nova_base}/servers/{server_id}/actionRequest body. flavorRef must be a different flavor UUID; resizing to the current flavor returns 400 Bad Request with When resizing, instances must change flavor!.
{ "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#
POST {nova_base}/servers/{server_id}/actionRequest body:
{ "confirmResize": null }Response: 204 No Content. Call this only once status is VERIFY_RESIZE; calling it earlier returns 409 conflictingRequest.
Revert resize#
POST {nova_base}/servers/{server_id}/actionRequest body:
{ "revertResize": null }Response: 202 Accepted. Call this only once status is VERIFY_RESIZE.
Create an image snapshot of an instance#
POST {nova_base}/servers/{server_id}/actionRequest body:
{ "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: 0Attach a volume to an instance#
POST {nova_base}/servers/{server_id}/os-volume_attachmentsRequest body:
{ "volumeAttachment": { "volumeId": "9e8d7c6b-5a4f-43e2-91d0-0c1b2a3d4e5f" } }Response: 200 OK.
{
"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#
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:
# 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#
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:
| Endpoint | Status |
|---|---|
GET {nova_base}/servers | 200 |
GET {nova_base}/servers/{server_id} | 200 |
POST {nova_base}/servers | 202 |
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_attachments | 200 |
DELETE {nova_base}/servers/{server_id}/os-volume_attachments/{attachment_id} | 202 |
Error envelopes are JSON, keyed by error class:
| Code | Envelope key | Meaning |
|---|---|---|
| 400 | badRequest | Malformed request, missing fields, or a no-op resize |
| 401 | unauthorized | Missing or expired X-Auth-Token |
| 403 | forbidden | Role lacks permission, or a zero-disk flavor without block_device_mapping_v2 |
| 404 | itemNotFound | Server, volume, or flavor UUID not found |
| 409 | conflictingRequest | Server is in the wrong vm_state or task_state for the action |
Example 409 envelope:
{
"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 untilstatusisACTIVEandOS-EXT-STS:task_stateisNone.Cannot 'confirmResize' instance ... while it is in vm_state active: the server has not reachedVERIFY_RESIZEyet. Wait untilstatusisVERIFY_RESIZEbefore callingconfirmResizeorrevertResize.
Status and task_state#
status | OS-EXT-STS:task_state | Meaning |
|---|---|---|
BUILD | scheduling, spawning | Instance is being created |
ACTIVE | None | Running and idle |
ACTIVE | non-None | An action is in flight |
SHUTOFF | None | Powered off |
HARD_REBOOT | reboot_started_hard | Hard reboot in progress |
RESIZE | resize_migrating | Migrating to the new flavor |
VERIFY_RESIZE | None | Waiting for confirmResize or revertResize |
ERROR | None | Build or migration failed; read the fault field |
DELETED | n/a | Deleted; GET returns 404 |