Storage

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.

Offer a volume to another project in the same tenant

POST
/scopes/{scopeId}/storage/volumes/{volumeId}/actions/transfer

Opens a TRANSFER OFFER for volumeId. Nothing is copied and nothing moves on the storage backend: the provider hands the volume's ownership to whoever presents the returned transferId together with the authKey, so the operation is independent of the volume's size and completes in milliseconds. Until someone accepts, the volume stays where it is and keeps billing to its current project. The authKey is returned by THIS call and never again. The provider stores only a hash of it and no later read can produce it; neither can this API. That is why this operation is synchronous 201 rather than 202 + Operation — routing a one-shot secret through an Operation result, or through an idempotency replay record, would turn it into a stored secret. Lose the key and the remedy is to withdraw the offer and open a new one. Validation: volumeId must exist in the scope (unknown → 404 NOT_FOUND); the volume must be AVAILABLE — an attached volume is refused with 409 CONFLICT, which is also the provider's own rule; a volume already offered is 409 CONFLICT. Caller needs owner|admin|contributor on the SOURCE scope (→ 403 FORBIDDEN). Async & state: Synchronous. The volume is not modified; no SSE frame is emitted, because nothing about the volume has changed yet. Errors: 401 unauthenticated; 403 no write role; 404 unknown scopeId/volumeId; 409 volume not AVAILABLE or already offered; 422 malformed body; 500 provider failure. Idempotency/Concurrency: Idempotency-Key is optional; when sent, the replay returns the original 201 — including the same authKey, because the replay is the same offer, not a second one. Two DIFFERENT keys against the same volume do not both succeed: the second is 409, so a retry storm cannot leave several live offers for one volume.

Authorization

bearerToken
headerAuthorizationBearer <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.

Path Parameters

scopeId*string

Opaque ownership+authorization scope resolving to tenant + subscription + project.

volumeId*string

Identifier of the block volume being offered.

Header Parameters

Idempotency-Key?string

Optional; 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.

Formatuuid

Request Body

application/json
  1. body

Payload for opening a volume transfer offer. Every field is optional - the volume is named by the path.

name?|

Optional label for the offer, shown to the donor while it is open.

Response Body

Offer opened. The authKey in this body is the only copy that will ever exist.

application/json
  1. response

The create response, and the ONLY place the authorization key ever appears. Treat it like a password - it is bearer proof of ownership over the volume until the offer is accepted or withdrawn.

transfer*

An open offer to hand a volume to another project. Carries no authorization key - the provider returns that only when the offer is created.

authKey*string

One-shot authorization key. Not retrievable afterwards from any endpoint; if it is lost, withdraw the offer and open a new one.

curl -X POST "https://example.com/scopes/string/storage/volumes/string/actions/transfer" \  -H "Content-Type: application/json" \  -d '{}'
{  "transfer": {    "id": "string",    "volumeId": "string",    "volumeName": "string",    "name": "string",    "createdAt": "2019-08-24T14:15:22Z"  },  "authKey": "string"}