Skip to content
qibdo qibdo
Theme
Book a demo

API standards

qibdo Cloud’s API follows the API Improvement Proposals (AIP). Every service exposes the same resource-oriented shape, so once you learn how one service works, you know how they all work.

The API Improvement Proposals are a well-documented, openly standardised set of rules, best practices, and patterns for API design. We adopted them deliberately: rather than invent platform-specific conventions, every service inherits one mature, consistent design language, the same one that large public clouds already use. Resources, collections, and the verbs that act on them follow the same rules everywhere, so learning one service lets you predict the rest, and an engineer who has used a public cloud is productive on qibdo from day one.

That choice is reinforced by how the API is built. Each service is defined once in gRPC and Protocol Buffers, which gives us a single, strongly-typed, well-defined contract. A gateway then transcodes between REST/JSON and gRPC in both directions, following AIP-127 (HTTP and gRPC transcoding): REST clients call ordinary HTTP/JSON endpoints, gRPC clients use the typed interface, and both reach the exact same API. There is no separate, hand-written REST layer that can drift from the contract.

Because that one contract is the source of truth, the OpenAPI specification, the generated SDKs, and these reference pages are all derived from it. What you read here is what the API actually does.

Resource-oriented design is the RESTful model: the API is organized around resources (a VM, a bucket, a role) grouped into collections, each addressed by a URL and manipulated with standard HTTP methods. qibdo adopts that model through AIP’s resource conventions (AIP-121) and exposes it over REST by transcoding the gRPC contract. URLs are hierarchical and name each parent in the path; the target resource is identified by {id}, and parents are named by their resource type.

# A workspace in Taxonomy
/taxonomy/v1/organisations/{organisation}/workspaces/{id}
# A virtual machine in Compute
/compute/v1/workspaces/{workspace}/zones/{zone}/engines/qibdo/vms/{id}

Most resources are scoped to a workspace, the boundary that every service uses to isolate your teams, environments, and projects (see Taxonomy).

Five standard methods cover the lifecycle of every resource. The verb, URL, and request body are consistent across services:

MethodHTTPPathBody
GetGET…/<collection>/{id}(none)
ListGET…/<collection>(none)
CreatePOST…/<collection>the resource
UpdatePATCH…/<collection>/{id}the resource + an update mask
DeleteDELETE…/<collection>/{id}(none)

For example, to create and then fetch a VM:

Terminal window
# Create (returns an operation, see Standard responses)
curl --request POST \
--url https://api.qibdo.example.com/compute/v1/workspaces/$WS/zones/$ZONE/engines/qibdo/vms \
--header "Authorization: Bearer $QIBDO_API_TOKEN" \
--header 'Content-Type: application/json' \
--data '{ "name": "web-1", "cpu": { "v_cpus_boot": 2 } }'
# Get
curl --url https://api.qibdo.example.com/compute/v1/workspaces/$WS/zones/$ZONE/engines/qibdo/vms/$ID \
--header "Authorization: Bearer $QIBDO_API_TOKEN"

Actions that don’t map cleanly to create/read/update/delete use a custom method: a verb appended to the resource URL after a colon. Lifecycle actions on a VM, for instance:

POST …/vms/{id}:start
POST …/vms/{id}:stop
POST …/vms/{id}:restart
POST …/vms/{id}:suspend
POST …/vms/{id}:resume
POST …/vms/{id}:reset

Other examples include …/workspaces/{id}:move and /iam/v1/tokens:revoke. Like the standard mutations, these custom methods return an operation.

Updates use PATCH with a field mask so you change only the fields you intend to:

  • Send the resource with the fields you want to set, plus an update_mask listing those field paths. Only the masked fields are written; everything else is left untouched.
  • Omit the mask to update every field present in your request body.
  • Use * as the mask for a full replacement (PUT-style semantics).

This makes partial updates safe and explicit: you never accidentally clear a field you didn’t send.

Listing: pagination, filtering, and ordering

Section titled “Listing: pagination, filtering, and ordering”

Every List endpoint accepts exactly four standard query parameters, and nothing else for narrowing results:

ParameterPurpose
page_sizeMaximum items per page (default 20, capped at 100).
page_tokenOpaque cursor for the next page (from a prior response’s next_page_token).
filterAn AIP-160 filter expression to narrow results.
order_byA comma-separated list of fields to sort by (append desc to reverse).

There are no per-field filter parameters; all filtering goes through the single filter string. See Filtering for the language, and Standard responses for the list response shape.

Some Get endpoints let you fetch a resource by its id without knowing which parent it lives under, by using - as that parent path segment (AIP-159). For example, to read a resource pool by id across every region and zone:

GET /topology/v1/regions/-/zones/-/resource-pools/{id}

You can substitute - for any parent the endpoint marks as supporting it, and you need permission at a scope that covers the resolved resource. Each resource’s reference notes which parents accept -; List endpoints do not (listing resource pools, for instance, is scoped to a single region and zone) and require every parent to be a concrete id.

The major version is part of the path (/compute/v1/..., /iam/v1/...). A new major version is introduced only for breaking changes and is served alongside the previous one; within a major version, changes are additive and backward-compatible.

  • snake_case fields. JSON field names mirror the Protobuf fields, in snake_case.
  • Server-managed fields are read-only. Fields such as id, created, and updated are output-only; if you send them on create or update, they’re ignored.
  • Timestamps are RFC 3339. For example 2026-06-04T12:30:00Z.