Create a node pool
const url = 'https://api.aetherplatform.cloud/api/v1/organizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/clusters/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/nodepools';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"name":"example","vcpus":1,"memory_gb":1,"disk_gb":1,"min_nodes":1,"max_nodes":1,"desired_nodes":1,"min_vcpus":1,"max_vcpus":1,"min_memory_gb":1,"max_memory_gb":1,"node_labels":{"additionalProperty":"example"},"node_taints":[{"key":"example","value":"example","effect":"NoSchedule"}],"drain_timeout_seconds":1,"scale_down_delay_seconds":1,"scale_down_utilization_percent":1}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.aetherplatform.cloud/api/v1/organizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/clusters/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/nodepools \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "name": "example", "vcpus": 1, "memory_gb": 1, "disk_gb": 1, "min_nodes": 1, "max_nodes": 1, "desired_nodes": 1, "min_vcpus": 1, "max_vcpus": 1, "min_memory_gb": 1, "max_memory_gb": 1, "node_labels": { "additionalProperty": "example" }, "node_taints": [ { "key": "example", "value": "example", "effect": "NoSchedule" } ], "drain_timeout_seconds": 1, "scale_down_delay_seconds": 1, "scale_down_utilization_percent": 1 }'Creates a node pool. Autoscaling is permitted; when min_nodes, desired_nodes, and max_nodes are equal the pool is fixed-size. Omitted bounds default to desired_nodes (which defaults to 1). Returns 202 while the pool provisions.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Organization UUID.
Cluster UUID.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Optional per-pool CPU autoscaling budget (total pool vCPUs); max > min ⇒ autoscaling. A non-zero minimum must cover at least one node; set BOTH min_vcpus and min_memory_gb to 0 (with the maxima set) to let the pool scale to zero nodes.
Optional per-pool CPU autoscaling budget (total pool vCPUs); max > min ⇒ autoscaling.
Optional per-pool memory autoscaling budget (total pool GB); max > min ⇒ autoscaling. A non-zero minimum must cover at least one node; set BOTH min_vcpus and min_memory_gb to 0 (with the maxima set) to let the pool scale to zero nodes.
Optional per-pool memory autoscaling budget (total pool GB); max > min ⇒ autoscaling.
Labels applied to the pool’s nodes at bootstrap. Reserved key prefixes (aether.cloud/, kubernetes.io/, k8s.io/, node-role.kubernetes.io/, node.kubernetes.io/) are rejected.
object
Taints applied to the pool’s nodes at bootstrap (create-only; immutable thereafter). Reserved key prefixes (aether.cloud/, kubernetes.io/, k8s.io/, node-role.kubernetes.io/, node.kubernetes.io/) are rejected, and a cluster must retain at least one pool with no NoSchedule/NoExecute taint.
object
How long to drain a node in this pool before deleting it anyway. Omit it (or send null) to use the platform default of 600s — the pool then tracks that default rather than being pinned to today’s value. 0 is rejected: it means “wait forever” to the underlying machinery, and one pod that refuses to evict would hang the pool’s teardown indefinitely.
How long a node in this pool must stay underutilised before the autoscaler removes it. Omit it (or send null) to use the platform default of 600s — the pool then tracks that default rather than being pinned to today’s value. This acts on the scale-down DECISION, while drain_timeout_seconds bounds the removal once it is decided. Accepted on any pool, but only autoscaling pools have an autoscaler node group, so on a fixed pool it is inert.
A node counts as underutilised when its CPU and memory requests are both below this share of allocatable capacity. Omit it (or send null) to use the platform default of 50.
Responses
Section titled “Responses”Node pool accepted for provisioning.
object
Optional per-pool CPU autoscaling budget (total pool vCPUs); max > min ⇒ autoscaling. A non-zero minimum must cover at least one node; set BOTH min_vcpus and min_memory_gb to 0 (with the maxima set) to let the pool scale to zero nodes.
Optional per-pool CPU autoscaling budget (total pool vCPUs); max > min ⇒ autoscaling.
Optional per-pool memory autoscaling budget (total pool GB); max > min ⇒ autoscaling. A non-zero minimum must cover at least one node; set BOTH min_vcpus and min_memory_gb to 0 (with the maxima set) to let the pool scale to zero nodes.
Optional per-pool memory autoscaling budget (total pool GB); max > min ⇒ autoscaling.
Labels applied to the pool’s nodes at bootstrap.
object
Taints applied to the pool’s nodes at bootstrap (set at create; immutable).
object
How long the platform drains a node in this pool before deleting it anyway. Omitted when the pool has none configured, which means the platform default of 600s applies (and keeps applying if that default changes).
How long a node in this pool must stay underutilised before the autoscaler removes it. Omitted when the pool has none configured, which means the platform default of 600s applies (and keeps applying if that default changes). Acts on the scale-down DECISION; drain_timeout_seconds bounds the removal once it is decided. Only autoscaling pools have an autoscaler node group, so on a fixed pool the value is stored and reported but has no effect.
A node counts as underutilised when its CPU and memory requests are both below this share of allocatable capacity. Omitted when the pool has none configured, which means the platform default of 50 applies.
Example
{ "node_taints": [ { "effect": "NoSchedule" } ], "status": "provisioning"}Invalid request. Includes no_schedulable_pool when the new pool’s taints would leave the cluster with no pool that can schedule workloads (a cluster must retain at least one pool with no NoSchedule/NoExecute taint).
object
object
A stable, machine-readable error code.
object
The platform status page (https://status.aetherplatform.cloud). Present on 5xx answers written by the API’s error writer and on no other; absent, not null, on 4xx.
The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.
Present on exactly these errors of the invoice pay and pay/confirm endpoints: 402 payment_declined, 402 payment_method_required, 409 invoice_already_paid, 409 invoice_not_issued, 409 invoice_below_minimum, 409 payment_not_in_flight, and 409 invoice_void when the void invoice was replaced. It is the id of the live invoice, which after a re-issue is the replacement and not the id in the request URL (on 409 invoice_void from pay/confirm it is the replacement’s id). Absent on every other error — 400 (including discount_code_invalid), 403, 404, the discount_* 409s, 409 invoice_void with no replacement (nothing live to name), every 5xx and 503 code — and never null.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": [ { "field": "example", "code": "example", "message": "example" } ], "status_url": "https://example.com", "decline_code": "example", "invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }}Missing or invalid credentials.
object
object
A stable, machine-readable error code.
object
The platform status page (https://status.aetherplatform.cloud). Present on 5xx answers written by the API’s error writer and on no other; absent, not null, on 4xx.
The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.
Present on exactly these errors of the invoice pay and pay/confirm endpoints: 402 payment_declined, 402 payment_method_required, 409 invoice_already_paid, 409 invoice_not_issued, 409 invoice_below_minimum, 409 payment_not_in_flight, and 409 invoice_void when the void invoice was replaced. It is the id of the live invoice, which after a re-issue is the replacement and not the id in the request URL (on 409 invoice_void from pay/confirm it is the replacement’s id). Absent on every other error — 400 (including discount_code_invalid), 403, 404, the discount_* 409s, 409 invoice_void with no replacement (nothing live to name), every 5xx and 503 code — and never null.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": [ { "field": "example", "code": "example", "message": "example" } ], "status_url": "https://example.com", "decline_code": "example", "invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }}Refused by the organization role policy (see Authorization in the API description). error.code is forbidden when the caller is not a member of the organization (or the API token belongs to another organization), insufficient_role when the caller’s organization role is below the operation’s minimum role, and token_not_permitted when the request was authenticated with an API token on an operation API tokens may not use (the API Tokens operations; the handler-gated operations named in the API description: deleting the organization, changing a member’s role or payment_mode, paying an invoice including its confirm step, and discounts; and for a cluster-pinned machine token every operation except the loadbalancer-ips and loadbalancer-vms operations). email_unverified when a portal user’s e-mail address is not verified (see Authentication).
object
object
A stable, machine-readable error code.
object
The platform status page (https://status.aetherplatform.cloud). Present on 5xx answers written by the API’s error writer and on no other; absent, not null, on 4xx.
The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.
Present on exactly these errors of the invoice pay and pay/confirm endpoints: 402 payment_declined, 402 payment_method_required, 409 invoice_already_paid, 409 invoice_not_issued, 409 invoice_below_minimum, 409 payment_not_in_flight, and 409 invoice_void when the void invoice was replaced. It is the id of the live invoice, which after a re-issue is the replacement and not the id in the request URL (on 409 invoice_void from pay/confirm it is the replacement’s id). Absent on every other error — 400 (including discount_code_invalid), 403, 404, the discount_* 409s, 409 invoice_void with no replacement (nothing live to name), every 5xx and 503 code — and never null.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": [ { "field": "example", "code": "example", "message": "example" } ], "status_url": "https://example.com", "decline_code": "example", "invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }}The requested resource was not found.
object
object
A stable, machine-readable error code.
object
The platform status page (https://status.aetherplatform.cloud). Present on 5xx answers written by the API’s error writer and on no other; absent, not null, on 4xx.
The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.
Present on exactly these errors of the invoice pay and pay/confirm endpoints: 402 payment_declined, 402 payment_method_required, 409 invoice_already_paid, 409 invoice_not_issued, 409 invoice_below_minimum, 409 payment_not_in_flight, and 409 invoice_void when the void invoice was replaced. It is the id of the live invoice, which after a re-issue is the replacement and not the id in the request URL (on 409 invoice_void from pay/confirm it is the replacement’s id). Absent on every other error — 400 (including discount_code_invalid), 403, 404, the discount_* 409s, 409 invoice_void with no replacement (nothing live to name), every 5xx and 503 code — and never null.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": [ { "field": "example", "code": "example", "message": "example" } ], "status_url": "https://example.com", "decline_code": "example", "invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }}The resource already exists or conflicts with current state.
object
object
A stable, machine-readable error code.
object
The platform status page (https://status.aetherplatform.cloud). Present on 5xx answers written by the API’s error writer and on no other; absent, not null, on 4xx.
The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.
Present on exactly these errors of the invoice pay and pay/confirm endpoints: 402 payment_declined, 402 payment_method_required, 409 invoice_already_paid, 409 invoice_not_issued, 409 invoice_below_minimum, 409 payment_not_in_flight, and 409 invoice_void when the void invoice was replaced. It is the id of the live invoice, which after a re-issue is the replacement and not the id in the request URL (on 409 invoice_void from pay/confirm it is the replacement’s id). Absent on every other error — 400 (including discount_code_invalid), 403, 404, the discount_* 409s, 409 invoice_void with no replacement (nothing live to name), every 5xx and 503 code — and never null.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": [ { "field": "example", "code": "example", "message": "example" } ], "status_url": "https://example.com", "decline_code": "example", "invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }}Request validation failed.
object
object
A stable, machine-readable error code.
object
The platform status page (https://status.aetherplatform.cloud). Present on 5xx answers written by the API’s error writer and on no other; absent, not null, on 4xx.
The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.
Present on exactly these errors of the invoice pay and pay/confirm endpoints: 402 payment_declined, 402 payment_method_required, 409 invoice_already_paid, 409 invoice_not_issued, 409 invoice_below_minimum, 409 payment_not_in_flight, and 409 invoice_void when the void invoice was replaced. It is the id of the live invoice, which after a re-issue is the replacement and not the id in the request URL (on 409 invoice_void from pay/confirm it is the replacement’s id). Absent on every other error — 400 (including discount_code_invalid), 403, 404, the discount_* 409s, 409 invoice_void with no replacement (nothing live to name), every 5xx and 503 code — and never null.
Examplegenerated
{ "error": { "code": "example", "message": "example", "details": [ { "field": "example", "code": "example", "message": "example" } ], "status_url": "https://example.com", "decline_code": "example", "invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0" }}