Preview — pending review
This reference is generated from the platform API contract and is still under review. Operations, fields, and descriptions can change before publication.
Change a volume's category (tier)
Moves the volume onto a different product category. Whether that is a provider operation
depends on the deployment, and the rule is deliberately the SAME one storage.volume.create
already uses: a category is programmed onto the provider only when this environment maps it
to a volume type the provider actually advertises. So:
- both categories map to real, advertised and DIFFERENT provider volume types → a real provider retype, which the provider may satisfy by MIGRATING the volume to another backend. That migration copies the data, so the Operation can stay pending for as long as the copy takes; the volume keeps its identity and its id throughout.
- otherwise (nothing mapped, or both categories land on the same provider type) → a
control-plane change only: the category and its price change, the provider is not called.
This is not a silent no-op — it is the same degrade create performs, and a category that
was ignored when the volume was created cannot coherently be enforced when it is changed.
Validation:
volumeIdmust exist in the scope (unknown → 404); the volume must be AVAILABLE — an attached volume is 409 CONFLICT, because a retype that turns into a migration cannot be performed under a live attachment in the general case;typemust be a known category and must DIFFER from the current one (→ 422 VALIDATION_FAILED). Caller needs owner|admin|contributor. Async & state: Asynchronous — 202 with an Operation.typeand the volume's price change on completion, emitted as aresource.updatedSSE frame (kindstorage.volume). Errors: 401; 403; 404; 409 volume not AVAILABLE; 412If-Matchmismatch; 422 unknown or unchanged category; 500 provider failure. Idempotency/Concurrency:Idempotency-Keyis optional (recommended);If-Matchguards against racing another mutation of the same volume.
bearerTokenAuthorizationBearer <token>An API token (pc_live_…) or a service-account key (sak_live_…), created in Identity & Access Management and sent as Authorization: Bearer <token>. Requests are rate limited per credential and per tenant: every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a refused request gets 429 RATE_LIMITED with Retry-After.
scopeId*stringOpaque ownership+authorization scope resolving to tenant + subscription + project.
volumeId*stringIdentifier of the block volume.
Idempotency-Key?stringOptional; recommended for safe retries. When sent, the same key+body within 24h replays the original result and the same key with a different body is 409 CONFLICT; keys are unique per tenant. When an API token or service-account (bearer) caller omits it, the request is applied once with no replay protection (a retry may apply it again). A console session gets one from the edge.
uuidIf-Match?stringETag for optimistic concurrency on mutations/deletes; mismatch results in 412.
application/json- body
Payload for changing a volume's category.
type*stringThe category to move the volume onto; must differ from its current one.
"Standard SSD""Premium SSD""Standard HDD"Retype accepted; returns the tracking Operation.
application/json- response
A long-running operation record. GET /operations/{operationId} returns its current state.
id*stringOperation identifier, unique platform-wide.
action*stringCanonical action id that started this operation, e.g. compute.instance.create.
state*OperationStateState machine for long-running operations. PENDING and RUNNING are transitional; the rest are terminal.
"PENDING""RUNNING""SUCCEEDED""FAILED""CANCELLED"resourceKind?|Kind of the target resource (matches RealtimeEvent.kind), null for resource-less actions.
resourceId?|Identifier of the target resource; null until the resource is allocated.
resourceName?|Human-readable name of the target resource captured when the operation was opened; null when unknown or the resource has been deleted (clients fall back to resourceId).
principalId?|Subject id (user id/email or service-account id) of the actor that initiated this operation, captured at the create chokepoint; null on internal/worker paths with no request-scoped principal or for historical rows. This is the real actor the Activity feed renders.
sourceIp?|Source IP address of the request that initiated this operation; null when unavailable (internal/worker paths, historical rows).
progressPercent?|Best-effort progress; null when the action does not report progress.
0 <= value <= 100error?|nullPopulated only when state is FAILED (or CANCELLED with partial rollback notes).
warning?|nullNon-fatal degradation recorded on an operation that still SUCCEEDED - the primary action completed but something explicitly requested could not be delivered (e.g. publicIp was requested at instance create but no floating IP could be assigned). On a CANCELLED create it reports that the provider resource had already been created and was kept (live and billed until deleted; details.disposition = left_in_place). Same code+message shape as error so clients render both uniformly; null when the operation ran without degradation.
startedAt?|When the worker began executing; null while PENDING.
finishedAt?|When a terminal state was reached; null while transitional.
createdAt*stringupdatedAt*stringcurl -X POST "https://example.com/scopes/string/storage/volumes/string/actions/retype" \ -H "Content-Type: application/json" \ -d '{ "type": "Standard SSD" }'{ "id": "string", "action": "string", "state": "PENDING", "resourceKind": "string", "resourceId": "string", "resourceName": "string", "principalId": "string", "sourceIp": "string", "progressPercent": 0, "error": { "code": "string", "message": "string", "field": "string", "details": {}, "retryable": false }, "warning": { "code": "string", "message": "string", "field": "string", "details": {}, "retryable": false }, "startedAt": "string", "finishedAt": "string", "createdAt": "string", "updatedAt": "string"}