curl --request POST \
--url https://storage.{region}.basaltic.sh/v1/volumes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "data-vol-01",
"volume_type": "ssd",
"size_gb": 100,
"performance": {
"iops": 6000,
"throughput_mib_s": 250
},
"description": "Primary data volume for app-01",
"tags": {
"environment": "production",
"team": "backend"
},
"architecture": "amd64",
"source_image": "ubuntu-24.04",
"source_snapshot": "019f24a8-4bbe-7441-93af-6bbac0413943",
"bootable": false
}
'import requests
url = "https://storage.{region}.basaltic.sh/v1/volumes"
payload = {
"name": "data-vol-01",
"volume_type": "ssd",
"size_gb": 100,
"performance": {
"iops": 6000,
"throughput_mib_s": 250
},
"description": "Primary data volume for app-01",
"tags": {
"environment": "production",
"team": "backend"
},
"architecture": "amd64",
"source_image": "ubuntu-24.04",
"source_snapshot": "019f24a8-4bbe-7441-93af-6bbac0413943",
"bootable": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'data-vol-01',
volume_type: 'ssd',
size_gb: 100,
performance: {iops: 6000, throughput_mib_s: 250},
description: 'Primary data volume for app-01',
tags: {environment: 'production', team: 'backend'},
architecture: 'amd64',
source_image: 'ubuntu-24.04',
source_snapshot: '019f24a8-4bbe-7441-93af-6bbac0413943',
bootable: false
})
};
fetch('https://storage.{region}.basaltic.sh/v1/volumes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://storage.{region}.basaltic.sh/v1/volumes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'data-vol-01',
'volume_type' => 'ssd',
'size_gb' => 100,
'performance' => [
'iops' => 6000,
'throughput_mib_s' => 250
],
'description' => 'Primary data volume for app-01',
'tags' => [
'environment' => 'production',
'team' => 'backend'
],
'architecture' => 'amd64',
'source_image' => 'ubuntu-24.04',
'source_snapshot' => '019f24a8-4bbe-7441-93af-6bbac0413943',
'bootable' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://storage.{region}.basaltic.sh/v1/volumes"
payload := strings.NewReader("{\n \"name\": \"data-vol-01\",\n \"volume_type\": \"ssd\",\n \"size_gb\": 100,\n \"performance\": {\n \"iops\": 6000,\n \"throughput_mib_s\": 250\n },\n \"description\": \"Primary data volume for app-01\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"architecture\": \"amd64\",\n \"source_image\": \"ubuntu-24.04\",\n \"source_snapshot\": \"019f24a8-4bbe-7441-93af-6bbac0413943\",\n \"bootable\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://storage.{region}.basaltic.sh/v1/volumes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"data-vol-01\",\n \"volume_type\": \"ssd\",\n \"size_gb\": 100,\n \"performance\": {\n \"iops\": 6000,\n \"throughput_mib_s\": 250\n },\n \"description\": \"Primary data volume for app-01\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"architecture\": \"amd64\",\n \"source_image\": \"ubuntu-24.04\",\n \"source_snapshot\": \"019f24a8-4bbe-7441-93af-6bbac0413943\",\n \"bootable\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://storage.{region}.basaltic.sh/v1/volumes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"data-vol-01\",\n \"volume_type\": \"ssd\",\n \"size_gb\": 100,\n \"performance\": {\n \"iops\": 6000,\n \"throughput_mib_s\": 250\n },\n \"description\": \"Primary data volume for app-01\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"architecture\": \"amd64\",\n \"source_image\": \"ubuntu-24.04\",\n \"source_snapshot\": \"019f24a8-4bbe-7441-93af-6bbac0413943\",\n \"bootable\": false\n}"
response = http.request(request)
puts response.read_body{
"volume": {
"id": "5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e",
"crn": "crn:storage:sa-saopaulo-1:my-account:volume/data-volume-01",
"name": "data-vol-01",
"tags": {
"environment": "production",
"team": "backend"
},
"volume_type": "ssd",
"size_gb": 100,
"performance": {
"requested": {
"iops": 3000,
"bytes_per_sec": 131072000,
"burst_iops": 0,
"burst_bytes_per_sec": 0,
"burst_seconds": 0
},
"applied": {
"iops": 3000,
"bytes_per_sec": 131072000,
"burst_iops": 0,
"burst_bytes_per_sec": 0,
"burst_seconds": 0
}
},
"included_io_limits": {
"iops": 3000,
"bytes_per_sec": 131072000,
"burst_iops": 0,
"burst_bytes_per_sec": 0,
"burst_seconds": 0
},
"status": "available",
"bootable": false,
"faults": [
{
"code": "BACKUP_FAILED",
"severity": "error",
"message": "Backup upload failed.",
"details": {},
"first_at": "2023-11-07T05:31:56Z",
"last_at": "2023-11-07T05:31:56Z",
"occurrences": 1
}
],
"created_at": "2026-01-15T09:30:00Z",
"updated_at": "2026-01-15T09:31:12Z",
"source_image": {
"id": "550e8400-e29b-41d4-a716-446655440004",
"crn": "crn:compute:sa-saopaulo-1:platform:image/ubuntu/architecture/amd64/version/24.04",
"name": "ubuntu"
},
"source_snapshot": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"crn": "crn:storage:sa-saopaulo-1:my-account:volume/data/snapshot/nightly",
"name": "nightly"
},
"description": "Primary data volume for app-01"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"params": {
"instances": 2,
"pools": 0
}
}
}{
"error": {
"code": "IDEMPOTENCY_KEY_REUSED",
"message": "This Idempotency-Key was already used with a different request payload",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}Create volume
Accept a volume creation request. The row is persisted in
status creating and provisioned asynchronously — poll GET
until status changes to available (success) or error,
with active faults.
curl --request POST \
--url https://storage.{region}.basaltic.sh/v1/volumes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "data-vol-01",
"volume_type": "ssd",
"size_gb": 100,
"performance": {
"iops": 6000,
"throughput_mib_s": 250
},
"description": "Primary data volume for app-01",
"tags": {
"environment": "production",
"team": "backend"
},
"architecture": "amd64",
"source_image": "ubuntu-24.04",
"source_snapshot": "019f24a8-4bbe-7441-93af-6bbac0413943",
"bootable": false
}
'import requests
url = "https://storage.{region}.basaltic.sh/v1/volumes"
payload = {
"name": "data-vol-01",
"volume_type": "ssd",
"size_gb": 100,
"performance": {
"iops": 6000,
"throughput_mib_s": 250
},
"description": "Primary data volume for app-01",
"tags": {
"environment": "production",
"team": "backend"
},
"architecture": "amd64",
"source_image": "ubuntu-24.04",
"source_snapshot": "019f24a8-4bbe-7441-93af-6bbac0413943",
"bootable": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'data-vol-01',
volume_type: 'ssd',
size_gb: 100,
performance: {iops: 6000, throughput_mib_s: 250},
description: 'Primary data volume for app-01',
tags: {environment: 'production', team: 'backend'},
architecture: 'amd64',
source_image: 'ubuntu-24.04',
source_snapshot: '019f24a8-4bbe-7441-93af-6bbac0413943',
bootable: false
})
};
fetch('https://storage.{region}.basaltic.sh/v1/volumes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://storage.{region}.basaltic.sh/v1/volumes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'data-vol-01',
'volume_type' => 'ssd',
'size_gb' => 100,
'performance' => [
'iops' => 6000,
'throughput_mib_s' => 250
],
'description' => 'Primary data volume for app-01',
'tags' => [
'environment' => 'production',
'team' => 'backend'
],
'architecture' => 'amd64',
'source_image' => 'ubuntu-24.04',
'source_snapshot' => '019f24a8-4bbe-7441-93af-6bbac0413943',
'bootable' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://storage.{region}.basaltic.sh/v1/volumes"
payload := strings.NewReader("{\n \"name\": \"data-vol-01\",\n \"volume_type\": \"ssd\",\n \"size_gb\": 100,\n \"performance\": {\n \"iops\": 6000,\n \"throughput_mib_s\": 250\n },\n \"description\": \"Primary data volume for app-01\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"architecture\": \"amd64\",\n \"source_image\": \"ubuntu-24.04\",\n \"source_snapshot\": \"019f24a8-4bbe-7441-93af-6bbac0413943\",\n \"bootable\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://storage.{region}.basaltic.sh/v1/volumes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"data-vol-01\",\n \"volume_type\": \"ssd\",\n \"size_gb\": 100,\n \"performance\": {\n \"iops\": 6000,\n \"throughput_mib_s\": 250\n },\n \"description\": \"Primary data volume for app-01\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"architecture\": \"amd64\",\n \"source_image\": \"ubuntu-24.04\",\n \"source_snapshot\": \"019f24a8-4bbe-7441-93af-6bbac0413943\",\n \"bootable\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://storage.{region}.basaltic.sh/v1/volumes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"data-vol-01\",\n \"volume_type\": \"ssd\",\n \"size_gb\": 100,\n \"performance\": {\n \"iops\": 6000,\n \"throughput_mib_s\": 250\n },\n \"description\": \"Primary data volume for app-01\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"architecture\": \"amd64\",\n \"source_image\": \"ubuntu-24.04\",\n \"source_snapshot\": \"019f24a8-4bbe-7441-93af-6bbac0413943\",\n \"bootable\": false\n}"
response = http.request(request)
puts response.read_body{
"volume": {
"id": "5f8d2c1a-9b3e-4d7a-8c6f-1e2a3b4c5d6e",
"crn": "crn:storage:sa-saopaulo-1:my-account:volume/data-volume-01",
"name": "data-vol-01",
"tags": {
"environment": "production",
"team": "backend"
},
"volume_type": "ssd",
"size_gb": 100,
"performance": {
"requested": {
"iops": 3000,
"bytes_per_sec": 131072000,
"burst_iops": 0,
"burst_bytes_per_sec": 0,
"burst_seconds": 0
},
"applied": {
"iops": 3000,
"bytes_per_sec": 131072000,
"burst_iops": 0,
"burst_bytes_per_sec": 0,
"burst_seconds": 0
}
},
"included_io_limits": {
"iops": 3000,
"bytes_per_sec": 131072000,
"burst_iops": 0,
"burst_bytes_per_sec": 0,
"burst_seconds": 0
},
"status": "available",
"bootable": false,
"faults": [
{
"code": "BACKUP_FAILED",
"severity": "error",
"message": "Backup upload failed.",
"details": {},
"first_at": "2023-11-07T05:31:56Z",
"last_at": "2023-11-07T05:31:56Z",
"occurrences": 1
}
],
"created_at": "2026-01-15T09:30:00Z",
"updated_at": "2026-01-15T09:31:12Z",
"source_image": {
"id": "550e8400-e29b-41d4-a716-446655440004",
"crn": "crn:compute:sa-saopaulo-1:platform:image/ubuntu/architecture/amd64/version/24.04",
"name": "ubuntu"
},
"source_snapshot": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"crn": "crn:storage:sa-saopaulo-1:my-account:volume/data/snapshot/nightly",
"name": "nightly"
},
"description": "Primary data volume for app-01"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "ACCESS_DENIED",
"message": "You don't have permission to perform this action",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INVALID_INPUT",
"message": "Invalid request parameters",
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"params": {
"instances": 2,
"pools": 0
}
}
}{
"error": {
"code": "IDEMPOTENCY_KEY_REUSED",
"message": "This Idempotency-Key was already used with a different request payload",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An internal error occurred",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}storage:CreateVolume. See STORAGE permissions for the full list, what each one covers, and an example policy.Authorizations
An OAuth 2.0 bearer token, sent as Authorization: Bearer <token>.
This is the recommended way to authenticate.
Get one by exchanging a service account's access key pair at
POST /v1/oauth/token with grant_type=client_credentials. It is the
standard client-credentials grant, so any OAuth-aware library will
obtain and refresh it for you.
curl -s -u "$KEY_ID:$SECRET" -d grant_type=client_credentials \
https://iam.basaltic.sh/v1/oauth/token
Tokens last an hour by default. The same access key pair is separately your AWS SigV4 credential for the S3-compatible object endpoint, which speaks nothing else.
Headers
Optional client-generated key that makes a create replay-safe. Retrying a request with the same key returns the original outcome verbatim instead of creating a duplicate resource. Reusing a key with a different request body is rejected (422); a request whose key is still being processed returns 409. Records are honored for 24 hours. Use a UUID or similarly unique token.
255Body
Resource names must not start with the literal crn: prefix or be UUIDs (canonical, compact, braced, or urn:uuid: forms, in either case).
1 - 128"data-vol-01"
The tiers a new volume may be provisioned on. hdd is a valid
stored tier but its pool is reserved for cold storage, so
creating a block volume on it is rejected.
ssd, nvme "ssd"
1 <= x <= 16384100
Independently provision total sustained, combined read/write performance. Omitted dimensions retain their current value (included allowance on create). SSD permits up to 8000 IOPS and 250 MiB/s; NVMe up to 12000 and 500 MiB/s. The minimum is the volume's included allowance; higher grandfathered allowances remain available free of charge. Throughput is whole MiB/s, except an exact fractional legacy allowance may be selected to remove the paid add-on. Increases require account quota, regional capacity, and healthy storage. Applied extras bill by elapsed duration, including while detached or stopped.
Show child attributes
Show child attributes
"Primary data volume for app-01"
Show child attributes
Show child attributes
{
"environment": "production",
"team": "backend"
}
Architecture used for source_image name resolution. A full image CRN pins its own architecture.
"amd64"
Image UUID, name, name:version, or full CRN image//architecture//version/. Names resolve in the caller account first, then tagged platform catalog images, using architecture (default amd64). Mutually exclusive with source_snapshot. Image tags are not accepted.
"ubuntu-24.04"
Clone from an available account-owned snapshot UUID or nested CRN volume//snapshot/. Bare snapshot names are rejected because this request has no fixed source volume. Mutually exclusive with source_image; size_gb must be at least the snapshot's frozen size.
"019f24a8-4bbe-7441-93af-6bbac0413943"
false
Response
Volume creation accepted (status=creating)
Show child attributes
Show child attributes

