curl --request POST \
--url https://api.rafftechnologies.com/api/v1/volumes \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-Project-ID: <x-project-id>' \
--data '
{
"name": "data-vol-1",
"size": 100,
"volume_type": "nvme",
"vm_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"region": "us-east"
}
'import requests
url = "https://api.rafftechnologies.com/api/v1/volumes"
payload = {
"name": "data-vol-1",
"size": 100,
"volume_type": "nvme",
"vm_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"region": "us-east"
}
headers = {
"X-Project-ID": "<x-project-id>",
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Project-ID': '<x-project-id>',
'X-API-Key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'data-vol-1',
size: 100,
volume_type: 'nvme',
vm_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
region: 'us-east'
})
};
fetch('https://api.rafftechnologies.com/api/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://api.rafftechnologies.com/api/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-1',
'size' => 100,
'volume_type' => 'nvme',
'vm_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'region' => 'us-east'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>",
"X-Project-ID: <x-project-id>"
],
]);
$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://api.rafftechnologies.com/api/v1/volumes"
payload := strings.NewReader("{\n \"name\": \"data-vol-1\",\n \"size\": 100,\n \"volume_type\": \"nvme\",\n \"vm_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"region\": \"us-east\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Project-ID", "<x-project-id>")
req.Header.Add("X-API-Key", "<api-key>")
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://api.rafftechnologies.com/api/v1/volumes")
.header("X-Project-ID", "<x-project-id>")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"data-vol-1\",\n \"size\": 100,\n \"volume_type\": \"nvme\",\n \"vm_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"region\": \"us-east\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rafftechnologies.com/api/v1/volumes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Project-ID"] = '<x-project-id>'
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"data-vol-1\",\n \"size\": 100,\n \"volume_type\": \"nvme\",\n \"vm_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"region\": \"us-east\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": 123,
"name": "data-vol-1",
"volume_type": "nvme",
"size": 100,
"status": "creating",
"account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"project_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"product_vm": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"price_per_hour": "<string>",
"region": "us-east",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "Payment Required",
"message": "Insufficient balance for subscription"
}{
"error": "Billing validation failed",
"reason": "banned",
"message": "Payment failed. Please update your payment method."
}Create Volume
Create a new block storage volume. Volumes are created asynchronously — the response returns immediately with pending status.
Optionally attach the volume to an existing VM at create time by passing vm_id. Volume and VM must be in the same region.
Filesystem
For Linux VMs, set filesystem_type to choose how the volume is formatted:
ext4(default),xfs,btrfs— Linux filesystems- Omit for Windows VMs — they always use NTFS
Filesystem is only applied if the volume is attached to a VM that mounts it via cloud-init or the contextualization script.
curl --request POST \
--url https://api.rafftechnologies.com/api/v1/volumes \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-Project-ID: <x-project-id>' \
--data '
{
"name": "data-vol-1",
"size": 100,
"volume_type": "nvme",
"vm_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"region": "us-east"
}
'import requests
url = "https://api.rafftechnologies.com/api/v1/volumes"
payload = {
"name": "data-vol-1",
"size": 100,
"volume_type": "nvme",
"vm_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"region": "us-east"
}
headers = {
"X-Project-ID": "<x-project-id>",
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Project-ID': '<x-project-id>',
'X-API-Key': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'data-vol-1',
size: 100,
volume_type: 'nvme',
vm_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
region: 'us-east'
})
};
fetch('https://api.rafftechnologies.com/api/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://api.rafftechnologies.com/api/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-1',
'size' => 100,
'volume_type' => 'nvme',
'vm_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'region' => 'us-east'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>",
"X-Project-ID: <x-project-id>"
],
]);
$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://api.rafftechnologies.com/api/v1/volumes"
payload := strings.NewReader("{\n \"name\": \"data-vol-1\",\n \"size\": 100,\n \"volume_type\": \"nvme\",\n \"vm_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"region\": \"us-east\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Project-ID", "<x-project-id>")
req.Header.Add("X-API-Key", "<api-key>")
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://api.rafftechnologies.com/api/v1/volumes")
.header("X-Project-ID", "<x-project-id>")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"data-vol-1\",\n \"size\": 100,\n \"volume_type\": \"nvme\",\n \"vm_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"region\": \"us-east\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rafftechnologies.com/api/v1/volumes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Project-ID"] = '<x-project-id>'
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"data-vol-1\",\n \"size\": 100,\n \"volume_type\": \"nvme\",\n \"vm_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"region\": \"us-east\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"id": 123,
"name": "data-vol-1",
"volume_type": "nvme",
"size": 100,
"status": "creating",
"account_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"project_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"product_vm": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"price_per_hour": "<string>",
"region": "us-east",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>",
"message": "<string>"
}{
"error": "Payment Required",
"message": "Insufficient balance for subscription"
}{
"error": "Billing validation failed",
"reason": "banned",
"message": "Payment failed. Please update your payment method."
}Authorizations
API key for authentication. Each key is bound to a specific account.
Headers
Project ID. Required for all mutating operations (create, delete, power actions, resize).
Body
Volume display name
1 - 64"data-vol-1"
Volume size in GB
x >= 1100
Storage class
nvme "nvme"
Filesystem to format the volume with on first attach. Linux only — Windows VMs use NTFS automatically. Defaults to ext4.
ext4, xfs, btrfs Optional. Attach the volume to this VM at create time. VM must be in the same region.
Region. Defaults to the project's default region.
us-east