curl --request PATCH \
--url https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"description": "Nightly background workers",
"tags": {
"environment": "production",
"team": "backend"
},
"desired_count": 3,
"min_count": 2,
"max_count": 6
}
'import requests
url = "https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}"
payload = {
"description": "Nightly background workers",
"tags": {
"environment": "production",
"team": "backend"
},
"desired_count": 3,
"min_count": 2,
"max_count": 6
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
description: 'Nightly background workers',
tags: {environment: 'production', team: 'backend'},
desired_count: 3,
min_count: 2,
max_count: 6
})
};
fetch('https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}', 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://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'description' => 'Nightly background workers',
'tags' => [
'environment' => 'production',
'team' => 'backend'
],
'desired_count' => 3,
'min_count' => 2,
'max_count' => 6
]),
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://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}"
payload := strings.NewReader("{\n \"description\": \"Nightly background workers\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"desired_count\": 3,\n \"min_count\": 2,\n \"max_count\": 6\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"description\": \"Nightly background workers\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"desired_count\": 3,\n \"min_count\": 2,\n \"max_count\": 6\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"description\": \"Nightly background workers\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"desired_count\": 3,\n \"min_count\": 2,\n \"max_count\": 6\n}"
response = http.request(request)
puts response.read_body{
"instance_pool": {
"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
}
],
"id": "8f2a1c3d-4e5b-4a6f-9c0d-1e2f3a4b5c6d",
"crn": "crn:compute:sa-saopaulo-1:my-account:instance-pool/web-pool",
"name": "web-asg",
"description": "Front-end autoscaling group",
"desired_count": 2,
"min_count": 1,
"max_count": 3,
"live_count": 2,
"member_count": 2,
"refresh_in_progress": false,
"stale_instance_count": 0,
"status": "active",
"managed_by": "customer",
"tags": {
"environment": "production",
"team": "backend"
},
"template": {
"flavor_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"image_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"networks": [
{
"subnet": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"crn": "crn:network:sa-saopaulo-1:my-account:vpc/prod/subnet/prod-web",
"vpc": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"crn": "crn:network:sa-saopaulo-1:my-account:vpc/prod",
"name": "prod",
"cidr_ipv4": "10.0.0.0/16",
"tags": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"description": "Production VPC for web and app tiers",
"cidr_ipv6": "2a13:9500:1a6:100::/60"
},
"route_table": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"crn": "crn:network:sa-saopaulo-1:my-account:vpc/prod/route-table/prod-private-rt",
"name": "prod-private-rt"
},
"name": "prod-web",
"cidr_ipv4": "10.0.1.0/24",
"gateway_ipv4": "10.0.1.1",
"tags": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"description": "Public web-tier subnet",
"cidr_ipv6": "2a13:9500:1a6:100::/64",
"gateway_ipv6": "2a13:9500:1a6:100::1"
},
"mac": "02:1a:2b:3c:4d:5e",
"security_group_ids": [
"c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f"
],
"floating_ip_assignment": "none",
"addresses": [
{
"family": "ipv4",
"address": "<string>"
}
]
}
],
"key_names": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"user_data": "aSDinaTvuI8gbWludGxpZnk=",
"metadata": {
"environment": "production",
"team": "backend"
},
"tags": {
"environment": "production",
"team": "backend"
},
"iam_role": {
"id": "b2c3d4e5-f6a7-8901-2345-67890abcdef1",
"crn": "crn:iam::my-account:role/deploy",
"name": "deploy"
},
"volumes": [
{
"size_gb": 20,
"boot": false,
"volume_type": "nvme",
"mount_path": "/data",
"fstype": "ext4",
"delete_on_termination": true
}
]
}
}
}{
"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": "NOT_FOUND",
"message": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}Update an instance pool's description, size, tags or launch template
curl --request PATCH \
--url https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"description": "Nightly background workers",
"tags": {
"environment": "production",
"team": "backend"
},
"desired_count": 3,
"min_count": 2,
"max_count": 6
}
'import requests
url = "https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}"
payload = {
"description": "Nightly background workers",
"tags": {
"environment": "production",
"team": "backend"
},
"desired_count": 3,
"min_count": 2,
"max_count": 6
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
description: 'Nightly background workers',
tags: {environment: 'production', team: 'backend'},
desired_count: 3,
min_count: 2,
max_count: 6
})
};
fetch('https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}', 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://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'description' => 'Nightly background workers',
'tags' => [
'environment' => 'production',
'team' => 'backend'
],
'desired_count' => 3,
'min_count' => 2,
'max_count' => 6
]),
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://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}"
payload := strings.NewReader("{\n \"description\": \"Nightly background workers\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"desired_count\": 3,\n \"min_count\": 2,\n \"max_count\": 6\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"description\": \"Nightly background workers\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"desired_count\": 3,\n \"min_count\": 2,\n \"max_count\": 6\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://compute.{region}.basaltic.sh/v1/instance-pools/{pool_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"description\": \"Nightly background workers\",\n \"tags\": {\n \"environment\": \"production\",\n \"team\": \"backend\"\n },\n \"desired_count\": 3,\n \"min_count\": 2,\n \"max_count\": 6\n}"
response = http.request(request)
puts response.read_body{
"instance_pool": {
"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
}
],
"id": "8f2a1c3d-4e5b-4a6f-9c0d-1e2f3a4b5c6d",
"crn": "crn:compute:sa-saopaulo-1:my-account:instance-pool/web-pool",
"name": "web-asg",
"description": "Front-end autoscaling group",
"desired_count": 2,
"min_count": 1,
"max_count": 3,
"live_count": 2,
"member_count": 2,
"refresh_in_progress": false,
"stale_instance_count": 0,
"status": "active",
"managed_by": "customer",
"tags": {
"environment": "production",
"team": "backend"
},
"template": {
"flavor_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"image_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"networks": [
{
"subnet": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"crn": "crn:network:sa-saopaulo-1:my-account:vpc/prod/subnet/prod-web",
"vpc": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"crn": "crn:network:sa-saopaulo-1:my-account:vpc/prod",
"name": "prod",
"cidr_ipv4": "10.0.0.0/16",
"tags": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"description": "Production VPC for web and app tiers",
"cidr_ipv6": "2a13:9500:1a6:100::/60"
},
"route_table": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"crn": "crn:network:sa-saopaulo-1:my-account:vpc/prod/route-table/prod-private-rt",
"name": "prod-private-rt"
},
"name": "prod-web",
"cidr_ipv4": "10.0.1.0/24",
"gateway_ipv4": "10.0.1.1",
"tags": {},
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"description": "Public web-tier subnet",
"cidr_ipv6": "2a13:9500:1a6:100::/64",
"gateway_ipv6": "2a13:9500:1a6:100::1"
},
"mac": "02:1a:2b:3c:4d:5e",
"security_group_ids": [
"c1d2e3f4-a5b6-4c7d-8e9f-0a1b2c3d4e5f"
],
"floating_ip_assignment": "none",
"addresses": [
{
"family": "ipv4",
"address": "<string>"
}
]
}
],
"key_names": [
"3c90c3cc-0d44-4b50-8888-8dd25736052a"
],
"user_data": "aSDinaTvuI8gbWludGxpZnk=",
"metadata": {
"environment": "production",
"team": "backend"
},
"tags": {
"environment": "production",
"team": "backend"
},
"iam_role": {
"id": "b2c3d4e5-f6a7-8901-2345-67890abcdef1",
"crn": "crn:iam::my-account:role/deploy",
"name": "deploy"
},
"volumes": [
{
"size_gb": 20,
"boot": false,
"volume_type": "nvme",
"mount_path": "/data",
"fstype": "ext4",
"delete_on_termination": true
}
]
}
}
}{
"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": "NOT_FOUND",
"message": "Resource not found",
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}compute:UpdateInstancePool. See COMPUTE 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.
Path Parameters
"8f2a1c3d-4e5b-4a6f-9c0d-1e2f3a4b5c6d"
Body
Every field is optional; sending none of them is a 400. Omitted bounds retain their current values. The resulting bounds must satisfy 0 <= min_count <= max_count <= 100, or the entire request returns 400. If desired_count is omitted, it is clamped into the resulting bounds. If supplied, desired_count must lie within those bounds or the entire request returns 400 with no changes applied. A changed target is reconciled normally. Managed pools are read-only through the customer API.
A refresh waits when max_count leaves no surge headroom; increasing max_count allows it to resume.
The two tag sets move independently. tags relabels the pool itself and
takes effect immediately, touching no instance. template.tags — like the
rest of template — does NOT touch the instances already running: a live
VM cannot change flavor, tier, subnet or its tags in place. It changes what
the pool launches NEXT, so until you roll the pool it holds members
carrying two different tag sets, and stale_instance_count is how many are
on the older one. Bring them onto the current template with
POST /v1/instance-pools/{pool_id}/refresh.
Customer note on the pool. Omit to preserve it; send an empty string to clear it. Changes no instances, sizing or launch configuration.
"Nightly background workers"
REPLACES the pool's labels: the map you send becomes the whole set, an empty object clears them, and omitting the field leaves them alone. Replacement rather than a merge because a merge leaves no way to say a key should be removed.
These label the pool, not its instances. To change what future replicas are tagged with, send template.tags.
Show child attributes
Show child attributes
{
"environment": "production",
"team": "backend"
}
New target size, bounded by the resulting min_count/max_count and the hard platform cap of 100.
0 <= x <= 1003
New lower bound; omitted desired_count rises to this bound if needed.
0 <= x <= 1002
New upper bound; omitted desired_count falls to this bound if needed. A value of 0 means the pool holds no members until max_count is raised.
0 <= x <= 1006
Replaces the launch config WHOLESALE — the object you send is what the pool launches next, and anything you leave out is cleared rather than kept. Replacement rather than a deep merge so a shorter networks or volumes cannot be read as a truncation and silently drop an interface or a disk.
Show child attributes
Show child attributes
Response
The updated instance pool.
A launch template plus a desired count. Creating a pool spawns desired_count instances; a reconciler converges member_count toward desired_count as it changes. member_count is how many members the pool holds; live_count is how many of them are running.
A pool carries two tag sets and they answer different questions. tags labels the pool resource — that is what an IAM condition reads as basalt:ResourceTag/<key> and what a cost report groups by, and it reaches no instance. template.tags is the set stamped on every replica the pool launches.
Show child attributes
Show child attributes

