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.
Retrieve a block volume detail read model
Returns the full block-volume read model for volumeId in the active scope, exactly as
the volume detail page renders it: identity (id, name, type), lifecycle status, size, attachment
(instance id/name and device path, or null), bootable/multi-attach flags, availability zone,
baseline latency, description, provenance (empty/image/snapshot source with its reference),
encryption posture (encrypted flag, KMS key id or platform-managed, automatic key-rotation
period in days), the per-GB monthly price in hundredths of the currency unit, and created/updated timestamps. Related panels
(snapshots, backup plans, replication targets, metrics, activity, tags) are loaded through
their own endpoints. No resource state is mutated.
Validation: scopeId must reference a scope the caller can read; volumeId must
reference an existing, non-deleted volume visible in that scope (unknown or soft-deleted →
404 NOT_FOUND); caller must hold reader-or-higher RBAC on the scope (→ 403 FORBIDDEN).
Async & state: Synchronous read; no state change. Subsequent attach/detach, resize and
status transitions arrive as resource.updated SSE frames (kind storage.volume, patch
{status, sizeGb, attachedTo, kmsKeyId, updatedAt}).
Errors: 401 missing/expired session; 403 caller lacks read access to the scope;
404 unknown scopeId or volumeId; 500 unexpected backend failure.
Idempotency/Concurrency: Safe, cacheable; no idempotency key required. The response
carries an ETag that later mutations (resize, attach, detach, delete) present via If-Match.
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.
Block volume read model.
application/json- response
Block volume read model as rendered by the Volumes page and the volume detail page.
origin?stringWhere the resource was made -- portal for a create on the console, api for an object made straight against the OpenStack API (CLI, Terraform, the Kubernetes cloud provider) that discovery adopted. Informational; nothing behaves differently. Absent from a backend that predates it, which means portal.
"portal""api""system""imported"id*stringVolume identifier (e.g. vol-0a1b2c3d).
name*stringVolume display name.
status*stringLifecycle status of the volume.
"CREATING""AVAILABLE""IN_USE""AWAITING_TRANSFER""ERROR"statusReason*|Human-readable, customer-facing reason for the current status when it is a failure (e.g. "This request exceeds the quota available to this project. Free up existing resources or request a quota increase." on an ERROR volume); never raw provider text. Null while the volume is healthy or the failure carried no detail.
statusReasonCode*|Machine-readable companion to statusReason: a small, OPEN vocabulary of codes the console can branch on without parsing the human text, deliberately a plain string rather than a closed enum so a code the client does not recognize yet degrades to the generic failure message. Today the only value is cancelled: the resource is in its failure state because its create operation was CANCELLED; a provider object the create had already built may be left in place, and the resource's DELETE removes it. Reported only while the resource is in that failure state; null otherwise.
sizeGb*integerProvisioned size in GB (1–16,384).
type*|Volume performance tier. Null when the volume sits on a provider volume type no platform tier maps to (e.g. a volume adopted from an imported project): the tier is then UNKNOWN and unpriced, never reported as a tier it is not. providerVolumeType carries the provider's own type name in that case.
providerVolumeType*|The provider's (Cinder's) own volume type name, present only when type is null because no platform tier maps to it (an adopted volume on a legacy type). Null for a volume on a platform tier. Display-only: it has no price and cannot be requested.
attachedTo*|nullInstance attachment (instance id, name, device), or null when detached.
bootable*booleanWhether the volume carries a bootable OS image.
encrypted*booleanWhether the volume is encrypted at rest, DERIVED from the provider's own view of the volume (the volume type's encryption spec) — never from the create request. False until the provider confirms encryption, so this field never asserts a security property the platform did not actually deliver.
multiAttach*booleanAllow attaching to more than one instance (RWX).
availabilityZone*stringAvailability zone the volume lives in (e.g. ist-1a).
description*stringOperator-supplied description.
source*Provenance of a block volume — empty, created from an image, restored from a snapshot, or cloned from another volume.
kmsKeyId*|Customer-managed KMS key for envelope encryption; null when platform-managed or encryption is off.
keyRotationDays*integerAutomatic key-rotation period in days (0 = manual).
pricePerGbMonthlyCents*|Price per GB per month in hundredths of the currency unit (an integer, not a Money object): the rate billing meters this volume's tier at for the volume's subscription, rounded down to the hundredth. Null when no price applies to the tier: there is no per-type default figure.
deletionProtection*booleanPlatform-owned deletion guard. While true, storage.volume.delete is refused with 409 DELETION_PROTECTED before any work starts; turn it off with the metadata PATCH, then delete. It guards the console and this API ONLY: Cinder has no lock, so an OpenStack API credential with Full access can still delete the volume directly. False for every volume unless a caller turned it on; the collector never writes it.
tags*array<>Key-value pairs shown on the Tags tab; double as Cost Explorer dimensions.
createdAt*stringCreation timestamp (ISO 8601).
date-timeupdatedAt*stringLast modification timestamp (ISO 8601).
date-timecurl -X GET "https://example.com/scopes/string/storage/volumes/string"{ "origin": "portal", "id": "string", "name": "string", "status": "CREATING", "statusReason": "string", "statusReasonCode": "string", "sizeGb": 0, "type": "Standard SSD", "providerVolumeType": "string", "attachedTo": { "instanceId": "string", "instanceName": "string", "device": "string" }, "bootable": true, "encrypted": true, "multiAttach": true, "availabilityZone": "string", "description": "string", "source": { "kind": "empty", "ref": "string" }, "kmsKeyId": "string", "keyRotationDays": 0, "pricePerGbMonthlyCents": 0, "deletionProtection": true, "tags": [ { "key": "string", "value": "string" } ], "createdAt": "2019-08-24T14:15:22Z", "updatedAt": "2019-08-24T14:15:22Z"}