curl --request POST \
--url https://api.rafftechnologies.com/api/v1/k8s/clusters \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-Project-ID: <x-project-id>' \
--data '
{
"name": "prod",
"node_pools": [
{
"name": "default-pool",
"node_count": 3,
"plan_id": 11,
"min_nodes": 123,
"max_nodes": 123,
"autoscale_enabled": false,
"labels": "<string>",
"taints": "<string>"
}
],
"k8s_version_id": 1,
"ha_enabled": false,
"firewall_enabled": true,
"firewall_security_group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"storage_node_count": 0,
"storage_node_disk_gb": 123,
"traefik_enabled": false,
"metallb_enabled": false,
"cluster_cidr": "10.42.0.0/16",
"service_cidr": "10.43.0.0/16",
"region": "us-east"
}
'import requests
url = "https://api.rafftechnologies.com/api/v1/k8s/clusters"
payload = {
"name": "prod",
"node_pools": [
{
"name": "default-pool",
"node_count": 3,
"plan_id": 11,
"min_nodes": 123,
"max_nodes": 123,
"autoscale_enabled": False,
"labels": "<string>",
"taints": "<string>"
}
],
"k8s_version_id": 1,
"ha_enabled": False,
"firewall_enabled": True,
"firewall_security_group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"storage_node_count": 0,
"storage_node_disk_gb": 123,
"traefik_enabled": False,
"metallb_enabled": False,
"cluster_cidr": "10.42.0.0/16",
"service_cidr": "10.43.0.0/16",
"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: 'prod',
node_pools: [
{
name: 'default-pool',
node_count: 3,
plan_id: 11,
min_nodes: 123,
max_nodes: 123,
autoscale_enabled: false,
labels: '<string>',
taints: '<string>'
}
],
k8s_version_id: 1,
ha_enabled: false,
firewall_enabled: true,
firewall_security_group_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
storage_node_count: 0,
storage_node_disk_gb: 123,
traefik_enabled: false,
metallb_enabled: false,
cluster_cidr: '10.42.0.0/16',
service_cidr: '10.43.0.0/16',
region: 'us-east'
})
};
fetch('https://api.rafftechnologies.com/api/v1/k8s/clusters', 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/k8s/clusters",
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' => 'prod',
'node_pools' => [
[
'name' => 'default-pool',
'node_count' => 3,
'plan_id' => 11,
'min_nodes' => 123,
'max_nodes' => 123,
'autoscale_enabled' => false,
'labels' => '<string>',
'taints' => '<string>'
]
],
'k8s_version_id' => 1,
'ha_enabled' => false,
'firewall_enabled' => true,
'firewall_security_group_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'storage_node_count' => 0,
'storage_node_disk_gb' => 123,
'traefik_enabled' => false,
'metallb_enabled' => false,
'cluster_cidr' => '10.42.0.0/16',
'service_cidr' => '10.43.0.0/16',
'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/k8s/clusters"
payload := strings.NewReader("{\n \"name\": \"prod\",\n \"node_pools\": [\n {\n \"name\": \"default-pool\",\n \"node_count\": 3,\n \"plan_id\": 11,\n \"min_nodes\": 123,\n \"max_nodes\": 123,\n \"autoscale_enabled\": false,\n \"labels\": \"<string>\",\n \"taints\": \"<string>\"\n }\n ],\n \"k8s_version_id\": 1,\n \"ha_enabled\": false,\n \"firewall_enabled\": true,\n \"firewall_security_group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"storage_node_count\": 0,\n \"storage_node_disk_gb\": 123,\n \"traefik_enabled\": false,\n \"metallb_enabled\": false,\n \"cluster_cidr\": \"10.42.0.0/16\",\n \"service_cidr\": \"10.43.0.0/16\",\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/k8s/clusters")
.header("X-Project-ID", "<x-project-id>")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"prod\",\n \"node_pools\": [\n {\n \"name\": \"default-pool\",\n \"node_count\": 3,\n \"plan_id\": 11,\n \"min_nodes\": 123,\n \"max_nodes\": 123,\n \"autoscale_enabled\": false,\n \"labels\": \"<string>\",\n \"taints\": \"<string>\"\n }\n ],\n \"k8s_version_id\": 1,\n \"ha_enabled\": false,\n \"firewall_enabled\": true,\n \"firewall_security_group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"storage_node_count\": 0,\n \"storage_node_disk_gb\": 123,\n \"traefik_enabled\": false,\n \"metallb_enabled\": false,\n \"cluster_cidr\": \"10.42.0.0/16\",\n \"service_cidr\": \"10.43.0.0/16\",\n \"region\": \"us-east\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rafftechnologies.com/api/v1/k8s/clusters")
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\": \"prod\",\n \"node_pools\": [\n {\n \"name\": \"default-pool\",\n \"node_count\": 3,\n \"plan_id\": 11,\n \"min_nodes\": 123,\n \"max_nodes\": 123,\n \"autoscale_enabled\": false,\n \"labels\": \"<string>\",\n \"taints\": \"<string>\"\n }\n ],\n \"k8s_version_id\": 1,\n \"ha_enabled\": false,\n \"firewall_enabled\": true,\n \"firewall_security_group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"storage_node_count\": 0,\n \"storage_node_disk_gb\": 123,\n \"traefik_enabled\": false,\n \"metallb_enabled\": false,\n \"cluster_cidr\": \"10.42.0.0/16\",\n \"service_cidr\": \"10.43.0.0/16\",\n \"region\": \"us-east\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"cluster": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"cluster_id": "q7z7zg",
"name": "prod",
"status": "pending",
"ready": true,
"status_message": "<string>",
"dns_domain": "q7z7zg.k8s.raffusercloud.com",
"api_endpoint": "https://q7z7zg.k8s.raffusercloud.com:6443",
"k8s_version": "v1.33.4+rke2r1",
"k8s_version_id": 123,
"region": "us-east",
"master_count": 123,
"worker_count": 123,
"ha_enabled": true,
"firewall_enabled": true,
"longhorn_enabled": true,
"traefik_enabled": true,
"metallb_enabled": true,
"billing_type": "payg",
"project_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"price_per_hour": 123,
"price_per_month": 123,
"vpc_id": "<string>",
"private_vip": "10.1.0.254",
"node_pools": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"node_count": 123,
"status": "pending",
"cluster_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"actual_node_count": 123,
"min_nodes": 123,
"max_nodes": 123,
"autoscale_enabled": true,
"plan_id": 123,
"cpu": 123,
"ram": 123,
"disk": 123,
"labels": "<string>",
"taints": "<string>",
"status_message": "<string>",
"nodes": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"pool_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"cluster_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"role": "vnf",
"status": "pending",
"cpu": 123,
"ram": 123,
"disk": 123,
"ip_address": "<string>",
"price_per_hour": 123,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
],
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
],
"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"
}Create Kubernetes Cluster
Create a managed Kubernetes cluster. Provisioning is asynchronous — the response returns immediately with pending status; the cluster is usable when ready is true (typically 8–12 minutes).
API-created clusters follow the account’s billing mode: pay-as-you-go accounts bill per node-hour; subscription accounts are billed monthly — the API validates the saved payment method, creates the subscription, and charges it automatically (same behavior as VM creation).
Retries are safe with an Idempotency-Key header: a repeated request with the same key returns the cluster created by the first request instead of provisioning a second one.
curl --request POST \
--url https://api.rafftechnologies.com/api/v1/k8s/clusters \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--header 'X-Project-ID: <x-project-id>' \
--data '
{
"name": "prod",
"node_pools": [
{
"name": "default-pool",
"node_count": 3,
"plan_id": 11,
"min_nodes": 123,
"max_nodes": 123,
"autoscale_enabled": false,
"labels": "<string>",
"taints": "<string>"
}
],
"k8s_version_id": 1,
"ha_enabled": false,
"firewall_enabled": true,
"firewall_security_group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"storage_node_count": 0,
"storage_node_disk_gb": 123,
"traefik_enabled": false,
"metallb_enabled": false,
"cluster_cidr": "10.42.0.0/16",
"service_cidr": "10.43.0.0/16",
"region": "us-east"
}
'import requests
url = "https://api.rafftechnologies.com/api/v1/k8s/clusters"
payload = {
"name": "prod",
"node_pools": [
{
"name": "default-pool",
"node_count": 3,
"plan_id": 11,
"min_nodes": 123,
"max_nodes": 123,
"autoscale_enabled": False,
"labels": "<string>",
"taints": "<string>"
}
],
"k8s_version_id": 1,
"ha_enabled": False,
"firewall_enabled": True,
"firewall_security_group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"storage_node_count": 0,
"storage_node_disk_gb": 123,
"traefik_enabled": False,
"metallb_enabled": False,
"cluster_cidr": "10.42.0.0/16",
"service_cidr": "10.43.0.0/16",
"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: 'prod',
node_pools: [
{
name: 'default-pool',
node_count: 3,
plan_id: 11,
min_nodes: 123,
max_nodes: 123,
autoscale_enabled: false,
labels: '<string>',
taints: '<string>'
}
],
k8s_version_id: 1,
ha_enabled: false,
firewall_enabled: true,
firewall_security_group_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
storage_node_count: 0,
storage_node_disk_gb: 123,
traefik_enabled: false,
metallb_enabled: false,
cluster_cidr: '10.42.0.0/16',
service_cidr: '10.43.0.0/16',
region: 'us-east'
})
};
fetch('https://api.rafftechnologies.com/api/v1/k8s/clusters', 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/k8s/clusters",
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' => 'prod',
'node_pools' => [
[
'name' => 'default-pool',
'node_count' => 3,
'plan_id' => 11,
'min_nodes' => 123,
'max_nodes' => 123,
'autoscale_enabled' => false,
'labels' => '<string>',
'taints' => '<string>'
]
],
'k8s_version_id' => 1,
'ha_enabled' => false,
'firewall_enabled' => true,
'firewall_security_group_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'storage_node_count' => 0,
'storage_node_disk_gb' => 123,
'traefik_enabled' => false,
'metallb_enabled' => false,
'cluster_cidr' => '10.42.0.0/16',
'service_cidr' => '10.43.0.0/16',
'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/k8s/clusters"
payload := strings.NewReader("{\n \"name\": \"prod\",\n \"node_pools\": [\n {\n \"name\": \"default-pool\",\n \"node_count\": 3,\n \"plan_id\": 11,\n \"min_nodes\": 123,\n \"max_nodes\": 123,\n \"autoscale_enabled\": false,\n \"labels\": \"<string>\",\n \"taints\": \"<string>\"\n }\n ],\n \"k8s_version_id\": 1,\n \"ha_enabled\": false,\n \"firewall_enabled\": true,\n \"firewall_security_group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"storage_node_count\": 0,\n \"storage_node_disk_gb\": 123,\n \"traefik_enabled\": false,\n \"metallb_enabled\": false,\n \"cluster_cidr\": \"10.42.0.0/16\",\n \"service_cidr\": \"10.43.0.0/16\",\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/k8s/clusters")
.header("X-Project-ID", "<x-project-id>")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"prod\",\n \"node_pools\": [\n {\n \"name\": \"default-pool\",\n \"node_count\": 3,\n \"plan_id\": 11,\n \"min_nodes\": 123,\n \"max_nodes\": 123,\n \"autoscale_enabled\": false,\n \"labels\": \"<string>\",\n \"taints\": \"<string>\"\n }\n ],\n \"k8s_version_id\": 1,\n \"ha_enabled\": false,\n \"firewall_enabled\": true,\n \"firewall_security_group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"storage_node_count\": 0,\n \"storage_node_disk_gb\": 123,\n \"traefik_enabled\": false,\n \"metallb_enabled\": false,\n \"cluster_cidr\": \"10.42.0.0/16\",\n \"service_cidr\": \"10.43.0.0/16\",\n \"region\": \"us-east\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.rafftechnologies.com/api/v1/k8s/clusters")
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\": \"prod\",\n \"node_pools\": [\n {\n \"name\": \"default-pool\",\n \"node_count\": 3,\n \"plan_id\": 11,\n \"min_nodes\": 123,\n \"max_nodes\": 123,\n \"autoscale_enabled\": false,\n \"labels\": \"<string>\",\n \"taints\": \"<string>\"\n }\n ],\n \"k8s_version_id\": 1,\n \"ha_enabled\": false,\n \"firewall_enabled\": true,\n \"firewall_security_group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"storage_node_count\": 0,\n \"storage_node_disk_gb\": 123,\n \"traefik_enabled\": false,\n \"metallb_enabled\": false,\n \"cluster_cidr\": \"10.42.0.0/16\",\n \"service_cidr\": \"10.43.0.0/16\",\n \"region\": \"us-east\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"cluster": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"cluster_id": "q7z7zg",
"name": "prod",
"status": "pending",
"ready": true,
"status_message": "<string>",
"dns_domain": "q7z7zg.k8s.raffusercloud.com",
"api_endpoint": "https://q7z7zg.k8s.raffusercloud.com:6443",
"k8s_version": "v1.33.4+rke2r1",
"k8s_version_id": 123,
"region": "us-east",
"master_count": 123,
"worker_count": 123,
"ha_enabled": true,
"firewall_enabled": true,
"longhorn_enabled": true,
"traefik_enabled": true,
"metallb_enabled": true,
"billing_type": "payg",
"project_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"price_per_hour": 123,
"price_per_month": 123,
"vpc_id": "<string>",
"private_vip": "10.1.0.254",
"node_pools": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"node_count": 123,
"status": "pending",
"cluster_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"actual_node_count": 123,
"min_nodes": 123,
"max_nodes": 123,
"autoscale_enabled": true,
"plan_id": 123,
"cpu": 123,
"ram": 123,
"disk": 123,
"labels": "<string>",
"taints": "<string>",
"status_message": "<string>",
"nodes": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"pool_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"cluster_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"role": "vnf",
"status": "pending",
"cpu": 123,
"ram": 123,
"disk": 123,
"ip_address": "<string>",
"price_per_hour": 123,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
],
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
],
"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"
}- A node plan ID — get one from List Kubernetes Node Plans
- A project ID for the
X-Project-IDheader — see Generate an API key - Optionally a version ID from List Kubernetes Versions (omit for the default)
402 — create the cluster from the dashboard instead. Retries are safe with an Idempotency-Key header.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).
Any unique string (max 128 chars). Reuse the same value when retrying a failed or timed-out request.
128Body
1–63 lowercase letters, digits or hyphens; unique within the account
"prod"
At least one pool with at least 2 nodes in total. Pools may use different plans — each pool's nodes are sized and billed by its own plan.
1Show child attributes
Show child attributes
From List Kubernetes versions. Omit for the default version.
1
3-master highly available control plane (flat monthly fee)
Attach the platform baseline firewall to the public gateway
Use one of your security groups instead of the baseline
Removed August 26, 2026 — every cluster includes the raff-block default StorageClass: PersistentVolumeClaims are provisioned as Volumes and billed per GB. Any value other than 0 is rejected.
Removed August 26, 2026 together with storage_node_count.
Install the Traefik ingress controller
Install MetalLB for LoadBalancer services
Pod network override (private IPv4, /12–/24)
Service network override (private IPv4, /12–/24)
us-east