REST API overview

Learn how the REST API is organized, from the base URL and scopes to asynchronous operations, idempotent writes, concurrency control, and errors.

The REST API is the HTTP API behind the console: the console sends its own requests to it. You call it with a bearer credential, send and receive JSON, and address most resources through the project they belong to.

Base URL

The API is served under /api/v1 on its own host, the API host, not on the console's host:

Base URL
https://<api-host>/api/v1
  • <api-host>: the host name of the API. It isn't the console's host.

Every path in this documentation and in the API reference is relative to this base URL. The REST equivalent on the last step of the instance creation wizard is a curl command with the same path and body. It's addressed to the console's host: to call the API from your own code, use the API host.

Interactive API explorer

The API host also serves the API reference as an interactive page, from which you can send requests in your browser:

Interactive API explorer
https://<api-host>/docs

Select Authorize, enter an API token or a service account key, and then use Try it out on an operation. The requests go to the API host with your credential and act on your real resources, so start with reads or with a project that you use for testing. The page keeps the credential only until you reload or close it. The OpenAPI document behind the page is at https://<api-host>/openapi.json; use it to generate a client or to import the API into an API tool.

The API reference on this site describes the same operations and doesn't send requests.

Scopes

Most resources belong to a project, and their paths start with /scopes/ followed by the project's ID:

Path of a project's instances
/scopes/<project-id>/compute/instances
  • <project-id>: the ID of the project that holds the resources.

The segment after the project ID names the service, such as compute, storage, or network. A few paths aren't under a project, for example /operations/<operation-id>. For the full path structure and how to find a project's ID, see Scopes, URLs, and request format.

Authentication

Every request carries a credential in the Authorization header: an API token, which starts with pc_live_, or a service account key, which starts with sak_live_. The API gateway checks the credential on every request and, for a project's resources, your access to that project, before the request reaches a service. For details, see Authenticate with API tokens.

Synchronous and asynchronous requests

Reads return 200 OK with the result. Writes return in one of two ways:

  • Synchronous. The change is complete when the response arrives: 200 OK or 201 Created with the result, or 204 No Content.
  • Asynchronous. The platform accepts the request and carries out the work in the cloud afterwards. The response is 202 Accepted. For example, creating an instance or a volume, deleting an instance, and starting or stopping an instance work this way.

The API reference shows the success status of each operation.

A 202 Accepted response has one of two bodies:

BodyHow to recognize itHow to follow the work
An operationIt has action and state fields.Read the operation until its state is final.
The resource in a transitional statusIt's the resource itself, for example a new instance in the BUILD status.Read the resource until its status settles.

If the operation in a 202 Accepted response is already SUCCEEDED, the work is complete. Billing writes, such as creating a budget or a commitment, answer this way, and their operations can't be read afterwards.

An operation tracks one asynchronous request. Read it with GET /operations/<operation-id>:

An operation that is still running
{
  "id": "3f2b8c1e9d4a4f6b8e2c7a1d5b9e0f42",
  "action": "compute.instance.stop",
  "state": "RUNNING",
  "resourceKind": "instance",
  "resourceId": "9c1d6e2a7b3f4c8d9e0a1b2c3d4e5f60",
  "resourceName": "web-01",
  "createdAt": "2026-10-08T09:30:00Z",
  "startedAt": "2026-10-08T09:30:01Z",
  "updatedAt": "2026-10-08T09:30:01Z"
}
StateMeaning
PENDINGThe request is accepted, and the work hasn't started.
RUNNINGThe work is in progress.
SUCCEEDEDThe work finished. If something that you asked for couldn't be delivered, warning says what. For example, an instance can be created without the public IP address that you requested.
FAILEDThe work failed. error carries the reason, in the same format as an error response.
CANCELLEDThe operation was canceled before it finished.

SUCCEEDED, FAILED, and CANCELLED are final. To cancel an operation that hasn't finished, send POST /operations/<operation-id>/actions/cancel with an Idempotency-Key header. Canceling an operation that has already finished returns 409 Conflict.

You can read an operation only when you can read its resource in its project; otherwise the API answers 404 Not Found. To cancel it, you need permission to manage that resource.

Timestamps in responses are ISO 8601 strings in UTC, as in the example.

Idempotent writes

Send an Idempotency-Key header with every write. If the network fails and you don't know whether a request arrived, send it again with the same key: the platform returns the result of the first request instead of applying the change a second time. A few operations ignore the key. For the rules and the exceptions, see Idempotent requests. With an API token or a service account key, a POST request that creates a resource is refused without the key: 400 Bad Request with the code IDEMPOTENCY_KEY_REQUIRED. On other writes the key is optional.

Concurrency control

Many resources return an ETag header when you read them. To make sure that you change the version you read, send that value in an If-Match header with the update. If the resource has changed in the meantime, the update returns 412 Precondition Failed: read the resource again and repeat the update.

Rename an instance only if it hasn't changed
curl -X PATCH "https://<api-host>/api/v1/scopes/<project-id>/compute/instances/<instance-id>" \
  -H "Authorization: Bearer $PC_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H 'If-Match: <etag>' \
  -H "Content-Type: application/json" \
  -d '{"name": "web-02"}'
  • <instance-id>: the ID of the instance.
  • <etag>: the exact value of the ETag header from your last read of the instance, such as W/"3a7bd3e2360a3d29eea436fcfb7e44c735d117c4".
  • PC_TOKEN: an environment variable that holds your API token.

These updates require If-Match. Without the header, they also return 412 Precondition Failed:

  • Updating an instance, a volume, a network, a subnet, a router, a security group, a network interface, or a load balancer.
  • Updating or deleting a backup plan.

For a subnet, send the ETag of its network. Subnets have no ETag of their own, and a subnet update returns the network's new ETag.

Lists and pagination

List operations return the items in data and the paging state in meta. For details, see Pagination.

Errors and rate limiting

Error responses from the API share one JSON shape, with a machine-readable code, a message, and, when a retry can succeed, "retryable": true. If you send requests too fast, the API returns 429 Too Many Requests with a Retry-After header. Every response to a request with an API token or a service account key carries the X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers; X-RateLimit-Reset is the number of seconds until the limit resets. For the codes and how to handle them, see Errors.

Request IDs

Every response carries an X-Request-Id header. If you send an X-Request-Id header yourself, the API uses your value; otherwise it generates one. Quote the ID when you report a problem with a request.

Versioning and changes

Within v1, the API changes only in backward-compatible ways. A breaking change is announced at least 6 months ahead, and the responses of the affected operation carry Deprecation and Sunset headers. For the rules, see API versioning and deprecation. For the changes, see the API changelog.

On this page