> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gcore.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage a Bare Metal GPU cluster

export const MethodSection = ({children}) => children ?? null;

export const MethodSwitch = ({children}) => {
  const tabs = React.Children.toArray(children).map(c => {
    if (!c || !c.props) return null;
    if (c.props.id) return c;
    const inner = c.props.children;
    if (inner && inner.props && inner.props.id) return inner;
    return null;
  }).filter(Boolean);
  const firstId = tabs.length > 0 ? tabs[0].props.id : "";
  const [active, setActive] = React.useState(firstId);
  React.useEffect(() => {
    try {
      const saved = localStorage.getItem("gcore_docs_method");
      if (saved && tabs.find(t => t.props.id === saved)) {
        setActive(saved);
      }
    } catch (_) {}
  }, []);
  React.useEffect(() => {
    try {
      document.querySelectorAll("h2[id], h3[id]").forEach(heading => {
        const visible = heading.offsetParent !== null;
        document.querySelectorAll(`a[href="#${heading.id}"]`).forEach(link => {
          if (link.closest("h1,h2,h3,h4,h5,h6")) return;
          const li = link.closest("li");
          if (li) li.style.display = visible ? "" : "none";
        });
      });
    } catch (_) {}
    window.dispatchEvent(new Event("scroll"));
  }, [active]);
  const handleClick = id => {
    setActive(id);
    try {
      localStorage.setItem("gcore_docs_method", id);
    } catch (_) {}
  };
  return <div>
      <div className="not-prose flex gap-0 border-b border-zinc-200 dark:border-zinc-800 mb-8 mt-2" role="tablist">
        {tabs.map(tab => {
    const isActive = active === tab.props.id;
    return <button key={tab.props.id} role="tab" aria-selected={isActive} onClick={() => handleClick(tab.props.id)} className={["px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors cursor-pointer", isActive ? "border-primary text-primary" : "border-transparent text-zinc-500 hover:text-zinc-800 dark:hover:text-zinc-200"].join(" ")}>
              {tab.props.label}
            </button>;
  })}
      </div>

      {tabs.map(tab => <div key={tab.props.id} style={{
    display: active === tab.props.id ? "" : "none"
  }}>
          {tab.props.children}
        </div>)}
    </div>;
};

<MethodSwitch>
  <MethodSection id="portal" label="Customer Portal">
    <p>After creating a GPU cluster, use the cluster details page to monitor nodes, manage cluster and node lifecycle, configure network interfaces, and access administration tools.</p>

    <p>Cluster management operates at two levels: cluster-wide operations (resize, reconfigure, delete) that affect all nodes at once, and per-node operations (rebuild, replace, power, apply settings) that target individual nodes independently.</p>

    ## Access cluster details

    1. In the [Gcore Customer Portal](https://portal.gcore.com), navigate to **GPU Cloud**.
    2. In the sidebar, expand **GPU Clusters** and select **Bare Metal GPU Clusters**.
    3. Click on a cluster name to open the details page.

    <p>The cluster details page shows the cluster name, current status badge, and cluster ID at the top. Below that, a header panel displays the following fields:</p>

    | Field     | Description                                                                                                  |
    | --------- | ------------------------------------------------------------------------------------------------------------ |
    | Pkey ID   | InfiniBand Partition Key ID. Displayed as "-" if InfiniBand is not configured or during cluster provisioning |
    | OS Distro | Operating system image installed on all nodes                                                                |
    | Region    | Data center location                                                                                         |
    | Plan      | Monthly pricing plan for the cluster                                                                         |

    <p>The page is organized into tabs: **Overview**, **Power**, **Networking**, **Tags**, **User Actions**, and **Delete**.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-overview.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=4ead7489311890b3129d995d33099a96" alt="Cluster overview page showing header panel and tabs" width="1095" height="756" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-overview.png" />
    </Frame>

    ## View cluster nodes

    <p>The **Overview** tab lists all nodes (servers) in the cluster. Each node entry shows the node name, flavor, assigned IP addresses, status, timestamps, cost, and other metadata. The table supports filtering by name, date range, and status.</p>

    <Info>
      Each node inherits its **cluster configuration** — image, SSH key, and user data — from the cluster. Network interfaces and file shares cannot be changed at the node level after creation. To update the cluster configuration, use **Reconfigure Cluster**; to sync a specific outdated node, use **Apply settings**.
    </Info>

    ## Cluster lifecycle

    <p>Cluster lifecycle operations control the cluster as a whole — adjusting its size, updating the shared configuration, and deleting it when no longer needed.</p>

    ### Manage cluster size

    <p>Cluster size can be adjusted after creation by adding or removing nodes.</p>

    1. On the **Overview** tab, click **Resize Cluster**.
    2. Adjust the instance count using the **+** and **-** buttons.
    3. Click **Resize**.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-resize-dialog.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=7a4b3576a6a2358a0b4b7d56a5fc9aec" alt="Resize cluster dialog with instance count controls" width="624" height="495" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-resize-dialog.png" />
    </Frame>

    <p>New nodes inherit the current cluster configuration. While resizing, most management actions are unavailable; Bare Metal H100 nodes may take 15–40 minutes to provision.</p>

    <Warning>
      Scaling down to zero nodes is not allowed. When scaling down, the system removes a random node — to target a specific node, use **Delete node** in [Node management](#node-management) instead.
    </Warning>

    ### Reconfigure cluster

    <p>The **Reconfigure Cluster** button in the top-right corner of the cluster details page opens a two-step flow for changing the cluster configuration and choosing how to apply it.</p>

    <p>**Step 1 — Update settings**</p>

    <p>The form shows the current **Image**, **SSH Key**, and **User data**, each with a dropdown labeled **Current**. Use the dropdown to select a new value, or leave it unchanged to keep the current setting. Click **Next** to proceed.</p>

    <p>**Step 2 — Choose update method**</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-reconfigure-step2.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=604793b1f9da34a0441ba2e87f57331b" alt="Reconfigure cluster page step 2 showing update method options" width="1124" height="833" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-reconfigure-step2.png" />
    </Frame>

    | Option                 | Description                                                                                                 |
    | ---------------------- | ----------------------------------------------------------------------------------------------------------- |
    | **Save only**          | The new configuration will be used for future scale-ups or the next rebuild. Existing nodes are unaffected. |
    | **Apply settings now** | Apply changes immediately to selected nodes or the entire cluster.                                          |
    | **Schedule for later** | Apply updates automatically at a specific time. Coming soon.                                                |

    <p>When **Apply settings now** is selected, select **All Instances in Cluster** or **Selected Instances** under **Apply to**. Click **Reconfigure** to confirm.</p>

    <Warning>
      Changes that require a node rebuild permanently delete all data on the system volume of affected nodes. IP addresses, hostname, and attached volumes are preserved.
    </Warning>

    ### Delete cluster

    <p>When a cluster is deleted, local NVMe storage is permanently erased; file shares and object storage remain intact.</p>

    1. Navigate to the **Delete** tab on the cluster details page.
    2. Click **Delete Cluster**.
    3. Confirm the deletion.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-delete-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=fe68f6ab6c9d9d06651252791f794466" alt="Delete tab with warning message and delete button" width="1096" height="479" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-delete-tab.png" />
    </Frame>

    <Warning>
      Cluster deletion is irreversible. Data on local NVMe storage cannot be recovered.
    </Warning>

    ## Node management

    <p>Node management operations target individual servers in the cluster independently — controlling power state, reinstalling the OS, swapping out failed nodes, and syncing updated cluster configuration to specific nodes.</p>

    ### Power actions

    <p>To control a single node:</p>

    1. Locate the node in the cluster list.
    2. Click the actions menu (three dots) on the node row.
    3. Select the desired action: **Power on**, **Power off**, **Soft reboot**, or **Hard reboot**.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/node-actions-menu.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=fd59e4f7fddc1cd03792b003b1e1ad64" alt="Node actions menu showing power and management options" width="1113" height="767" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/node-actions-menu.png" />
    </Frame>

    <p>To apply power actions to multiple nodes at once, select them using the checkboxes, click **Group actions**, and choose the action. Alternatively, use the **Power** tab to soft or hard reboot all cluster nodes simultaneously.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-power-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=1ab63e2919d82b2a7123454800a0db8b" alt="Power tab with soft and hard reboot options" width="1089" height="765" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-power-tab.png" />
    </Frame>

    ### Rebuild node

    <p>Rebuild reinstalls the OS on a node. The dialog shows the current **Image**, **SSH Key**, and **User data**. Use the dropdown next to any field to select a new value for this rebuild, or leave it unchanged to keep the current setting. All data on local storage is deleted.</p>

    1. Click the actions menu (three dots) on the node row.
    2. Select **Rebuild**.
    3. In the dialog, change **Image**, **SSH Key**, or **User data** as needed, or leave them to keep current values.
    4. Type `Rebuild` to confirm and click **Rebuild**.

    <p>To rebuild multiple nodes at once, select them using checkboxes, click **Group actions**, and select **Rebuild**. The dialog offers two modes: **Apply same settings to all Instances** or **Per Instance configuration**.</p>

    <Warning>
      Rebuild deletes all data on the node's local storage. Node identity is preserved — IP addresses, hostname, and attached volumes remain unchanged.
    </Warning>

    ### Replace node

    <p>Replace deletes the current node and provisions a new one with the same configuration (flavor, image, network settings). Use this to recover a node stuck in a failed state without changing the cluster setup.</p>

    1. Click the actions menu (three dots) on the node row.
    2. Select **Replace**.
    3. Confirm the operation.

    ### Delete node

    <p>To permanently remove a single node from the cluster:</p>

    1. Locate the node in the cluster list.
    2. Click the actions menu (three dots) on the node row.
    3. Select **Delete**.
    4. Confirm the deletion.

    <Warning>
      Deleting the last node in a cluster automatically deletes the entire cluster. This applies to both UI and API/Terraform operations. When using the API or Terraform to delete nodes, no warning is displayed before the cluster is removed. Leave at least one node in the cluster to preserve it.
    </Warning>

    ### Apply settings

    <p>When a node's cluster configuration is outdated — because the cluster was reconfigured but that node was not yet updated — a warning appears in the node details panel.</p>

    1. Click a node name in the **Overview** tab to open its details panel.
    2. Click **Apply settings**.
    3. Review the diff table: each row shows the **Setting**, **Current** value, and **After Apply** value.
    4. Select or deselect nodes to include.
    5. Type `Apply` and click **Apply**.

    <p>To apply settings to multiple outdated nodes at once, select them using checkboxes in the **Overview** tab, click **Group actions**, and select **Apply settings**.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/node-details-panel.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=fd6a19a2b7a6533dcd419282a4310e61" alt="Node details panel showing Apply settings and Rebuild buttons with outdated configuration warning" width="1440" height="900" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/node-details-panel.png" />
    </Frame>

    ## Networking

    <p>Network interfaces are assigned to each node at cluster creation. The Networking tab provides visibility into each node's interfaces and supports adding new ones after creation.</p>

    ### View interfaces

    <p>The **Networking** tab displays network interfaces for each node. Click a node name to expand its interface details.</p>

    | Type       | Description                                                             |
    | ---------- | ----------------------------------------------------------------------- |
    | Public     | External IP address for internet access                                 |
    | Private    | Internal network for communication with other cloud resources           |
    | InfiniBand | High-speed, low-latency inter-node network for GPU-to-GPU communication |

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-networking-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=759ee49ceb7c20a1b3c9b039d238a86c" alt="Networking tab showing node and interface list" width="1089" height="502" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-networking-tab.png" />
    </Frame>

    <p>For flavors with InfiniBand, multiple InfiniBand interfaces are created automatically (by default, 8 for H100 configurations). These appear as "GPU-cluster ib-subnet" entries in the interface list. Click on an interface to expand its details, including IP address and network configuration.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-network-interfaces.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=02522c6a6b0e0cc1679cadd0dec3bde2" alt="Node with expanded interface showing network details" width="1086" height="830" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-network-interfaces.png" />
    </Frame>

    ### Modify interfaces

    <p>To add network interfaces on a specific node:</p>

    1. Navigate to the **Networking** tab.
    2. Click a node to expand its details.
    3. Click **Add Interface** or **Add Sub-Interface**.
    4. Configure the interface type (public or private) and IP allocation settings as supported by the service.

    <Info>
      Only network interfaces can be modified on individual nodes after cluster creation. Image and storage configuration cannot be changed independently at the node level. InfiniBand interfaces are managed automatically and cannot be modified or deleted.
    </Info>

    ## Administration

    <p>Administrative tools for organizing clusters with tags, tracking operations through the audit log, and accessing nodes for troubleshooting via the browser console.</p>

    ### Tags

    <p>Tags are applied at the cluster level and inherited by all nodes.</p>

    1. Navigate to the **Tags** tab on the cluster details page.
    2. Enable the **Add custom tags** checkbox.
    3. Enter the key and value for each tag.
    4. Click **Save changes**.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-tags-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=af7d7059e85f6ae13a964763df615331" alt="Tags tab with custom tags toggle" width="1091" height="490" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-tags-tab.png" />
    </Frame>

    <p>Tags can be modified even while the cluster is in the Resizing state.</p>

    ### User actions

    <p>The **User Actions** tab displays a log of all operations performed on the cluster — creation, deletion, resize, power, and network actions. Use the date and action type filters to narrow results.</p>

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-user-actions-tab.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=9069767d708bca503b5f80db4497cc3b" alt="User Actions tab showing audit log of cluster operations" width="1098" height="622" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-user-actions-tab.png" />
    </Frame>

    ### Console

    <p>For troubleshooting or when SSH access is unavailable, use the browser-based console.</p>

    1. In the **Overview** tab, locate the target node.
    2. Click **Open Console** in the node row.
    3. The console opens in a new browser tab using noVNC.
    4. Log in with the same credentials used for SSH access.

    <Frame>
      <img src="https://mintcdn.com/gcore/IFamTPZ0eX9xxcmf/images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-console.png?fit=max&auto=format&n=IFamTPZ0eX9xxcmf&q=85&s=2a250b0afe0fc87400415e451d859095" alt="Browser-based noVNC console with login prompt" width="1366" height="328" data-path="images/docs/edge-ai/ai-infrastructure/manage-a-bare-metal-gpu-cluster/cluster-console.png" />
    </Frame>

    <p>The Customer Portal is suitable for managing individual clusters. For automated workflows — CI/CD pipelines, infrastructure-as-code, or batch provisioning — use the [GPU Bare Metal API](/api-reference/cloud/gpu-bare-metal) instead.</p>
  </MethodSection>

  <MethodSection id="api" label="REST API">
    <p>Use the REST API to inspect clusters, resize them, manage node lifecycle operations, and automate cluster administration workflows.</p>

    <Info>
      An [API token](/account-settings/api-tokens) is required, along with a
      [project ID](/api-reference/cloud/projects/list-projects)
      and a [region ID](/api-reference/cloud/regions/list-regions).
    </Info>

    <p>Open a terminal and set these environment variables before running the examples:</p>

    ```bash theme={null}
    export GCORE_API_KEY="{YOUR_API_KEY}"
    export GCORE_CLOUD_PROJECT_ID="{YOUR_PROJECT_ID}"
    export GCORE_CLOUD_REGION_ID="{YOUR_REGION_ID}"
    ```

    <Info>
      Most write operations are asynchronous and return `{ "tasks": ["task-uuid"] }`. Poll <code>GET /cloud/v1/tasks/\{task\_id}</code> every 5 seconds until `state` is `FINISHED`. Bare Metal H100 nodes may take 15–40 minutes for provisioning operations.
    </Info>

    ## List bare metal GPU clusters

    <p>The list endpoint returns all clusters in a project and region. Use query filters to narrow results — multiple filters are ANDed, so a cluster must match all specified conditions.</p>

    <p>Available filters:</p>

    | Filter          | Operators                               | Description                                                                                                     |
    | --------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
    | `ids`           | —                                       | Return clusters with specific IDs. Repeat the parameter for multiple values: `ids=uuid1&ids=uuid2`              |
    | `name`          | `contains`, `exact`, `prefix`, `suffix` | Match cluster name (case-insensitive)                                                                           |
    | `flavor`        | `contains`, `exact`, `prefix`, `suffix` | Match flavor name (case-insensitive)                                                                            |
    | `image_ids`     | —                                       | Return clusters provisioned with specific image IDs. Repeat for multiple values                                 |
    | `servers_count` | `gte`, `lte`, `gt`, `lt`                | Filter by node count                                                                                            |
    | `managed_by`    | —                                       | Return clusters by management type. Accepted values: `user` (directly managed) or `k8s` (managed by Kubernetes) |
    | `created_at`    | `gt`, `gte`, `lt`, `lte`                | Filter by creation time (UTC ISO 8601)                                                                          |
    | `updated_at`    | `gt`, `gte`, `lt`, `lte`                | Filter by last-update time (UTC ISO 8601)                                                                       |
    | `tags`          | `[key]=value`                           | Exact tag key-value pair. Multiple pairs are ANDed; values match case-insensitively                             |
    | `tag_key`       | `contains`, `exact`, `prefix`, `suffix` | Match tag key regardless of value                                                                               |
    | `tag_value`     | `contains`, `exact`, `prefix`, `suffix` | Match tag value regardless of key                                                                               |

    <Info>
      The Python and Go SDKs support `limit` and `offset` for pagination only. Name, flavor, node count, tag, image, and date filters are available via curl only.
    </Info>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

        page = client.cloud.gpu_baremetal.clusters.list(
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
        )
        for cluster in page.results:
            print(cluster.id, cluster.name, cluster.servers_count, cluster.status)
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            gcore "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))

            page, err := client.Cloud.GPUBaremetal.Clusters.List(context.TODO(),
                cloud.GPUBaremetalClusterListParams{
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("Total: %d\n", len(page.Results))
            for _, c := range page.Results {
                fmt.Printf("  %s  %s  nodes=%d\n", c.ID, c.Name, c.ServersCount)
            }
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -G "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          --data-urlencode "name[prefix]=prod-" \
          --data-urlencode "flavor[prefix]=bm3-" \
          --data-urlencode "servers_count[gte]=4" \
          --data-urlencode "tags[env]=production"
        ```

        Response:

        ```json theme={null}
        {
          "count": 1,
          "results": [
            {
              "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
              "name": "prod-bm-cluster-1",
              "status": "active",
              "flavor": "bm3-ai-1xlarge-h100-80-8",
              "tags": [
                { "key": "env", "value": "production", "read_only": false },
                { "key": "team", "value": "ml", "read_only": false }
              ],
              "servers_count": 4,
              "created_at": "2026-06-10T12:00:00Z",
              "updated_at": "2026-06-10T12:15:00Z",
              "servers_ids": [
                "server-uuid-1",
                "server-uuid-2",
                "server-uuid-3",
                "server-uuid-4"
              ],
              "has_pending_changes": false
            }
          ]
        }
        ```

        Use `limit` and `offset` for pagination. The default page size is 10; the maximum is 1000.
      </Tab>
    </Tabs>

    ## Get cluster details

    <p>Returns the full configuration and current status of a single cluster.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

        cluster = client.cloud.gpu_baremetal.clusters.get(
            cluster_id="{CLUSTER_ID}",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
        )
        print(cluster.id, cluster.name, cluster.status, cluster.servers_count)
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))

            cluster, err := client.Cloud.GPUBaremetal.Clusters.Get(context.TODO(),
                "{CLUSTER_ID}",
                cloud.GPUBaremetalClusterGetParams{
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%s  %s  nodes=%d\n", cluster.ID, cluster.Name, cluster.ServersCount)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        {
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "name": "prod-bm-cluster-1",
          "status": "active",
          "flavor": "bm3-ai-1xlarge-h100-80-8",
          "servers_count": 4,
          "servers_ids": ["server-uuid-1", "server-uuid-2", "server-uuid-3", "server-uuid-4"],
          "tags": [{ "key": "env", "value": "production" }],
          "created_at": "2026-06-10T12:00:00Z",
          "updated_at": "2026-06-10T12:15:00Z",
          "has_pending_changes": false
        }
        ```
      </Tab>
    </Tabs>

    ## Resize a cluster

    <p>Change the node count by specifying the new total number of nodes. Scaling down removes a random node; to delete a specific node, use the [Delete a specific node](#delete-a-specific-node) endpoint instead.</p>

    <Warning>
      Scaling down to zero is not allowed. A cluster must contain at least one node at all times.
    </Warning>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

        task_id_list = client.cloud.gpu_baremetal.clusters.resize(
            cluster_id="{CLUSTER_ID}",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
            instances_count=4,
        )
        print(task_id_list.tasks)
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Resize(context.TODO(),
                "{CLUSTER_ID}",
                cloud.GPUBaremetalClusterResizeParams{
                    ProjectID:      gcore.Int(projectID),
                    RegionID:       gcore.Int(regionID),
                    InstancesCount: 4,
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X POST \
          "https://api.gcore.com/cloud/v1/ai/clusters/gpu/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/{CLUSTER_ID}/resize" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          -H "Content-Type: application/json" \
          -d '{"instances_count": 4}'
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Control cluster power state

    <p>The `action` endpoint applies a power operation to all nodes in the cluster simultaneously.</p>

    | Action        | Description                          |
    | ------------- | ------------------------------------ |
    | `start`       | Power on all nodes                   |
    | `stop`        | Power off all nodes                  |
    | `soft_reboot` | Send ACPI shutdown signal and reboot |
    | `hard_reboot` | Force-reset all nodes immediately    |

    <Info>
      The Python and Go SDKs (v0.48.0) do not expose the cluster action endpoint directly. Use the curl tab below.
    </Info>

    <Tabs>
      <Tab title="curl">
        ```bash theme={null}
        # Replace "soft_reboot" with "start", "stop", or "hard_reboot"
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/action" \
          -H "Authorization: APIKey ${GCORE_API_KEY}" \
          -H "Content-Type: application/json" \
          -d '{"action": "soft_reboot"}'
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Rebuild a cluster

    <p>Reinstalls the OS on all nodes in the cluster using the cluster's current image, SSH key, and user data. All local storage data is erased.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

        task_id_list = client.cloud.gpu_baremetal.clusters.rebuild(
            cluster_id="{CLUSTER_ID}",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
        )
        print(task_id_list.tasks)
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Rebuild(context.TODO(),
                "{CLUSTER_ID}",
                cloud.GPUBaremetalClusterRebuildParams{
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/rebuild" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Rebuild a specific node

    <p>Reinstalls the OS on a single node without affecting other nodes in the cluster. All local storage on the node is erased. The rebuild uses the image, SSH key, and user data currently configured in the cluster's server settings — to use different values, first update the server settings via <code>PATCH /cloud/v3/gpu/baremetal/\{project\_id}/\{region\_id}/clusters/\{cluster\_id}/servers\_settings</code>, then trigger the rebuild.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

        task_id_list = client.cloud.gpu_baremetal.clusters.servers.rebuild(
            server_id="{SERVER_ID}",
            cluster_id="{CLUSTER_ID}",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
        )
        print(task_id_list.tasks)
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Servers.Rebuild(context.TODO(),
                "{SERVER_ID}",
                cloud.GPUBaremetalClusterServerRebuildParams{
                    ClusterID: "{CLUSTER_ID}",
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/servers/{SERVER_ID}/rebuild" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Replace a specific node

    <p>Deletes a node and provisions a new one with the same configuration. Use this to recover a node stuck in a failed state without changing the cluster setup.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

        task_id_list = client.cloud.gpu_baremetal.clusters.servers.replace(
            server_id="{SERVER_ID}",
            cluster_id="{CLUSTER_ID}",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
        )
        print(task_id_list.tasks)
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Servers.Replace(context.TODO(),
                "{SERVER_ID}",
                cloud.GPUBaremetalClusterServerReplaceParams{
                    ClusterID: "{CLUSTER_ID}",
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/servers/{SERVER_ID}/replace" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Apply settings to a node

    <p>Syncs a specific node that has outdated cluster configuration. The node must have `has_pending_changes=true`. To apply settings to all nodes at once, use `POST /cloud/v3/gpu/baremetal/{project_id}/{region_id}/clusters/{cluster_id}/apply_settings` without specifying a server ID.</p>

    <Tabs>
      <Tab title="curl">
        ```bash theme={null}
        # Apply to a specific node
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/servers/{SERVER_ID}/apply_settings" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"

        # Apply to all nodes in the cluster
        curl -X POST \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}/apply_settings" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Delete a specific node

    <p>Removes a single node by ID. If deleting the last node in the cluster, the entire cluster is removed — no confirmation prompt is shown through the API.</p>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

        task_id_list = client.cloud.gpu_baremetal.clusters.servers.delete(
            instance_id="{SERVER_ID}",
            cluster_id="{CLUSTER_ID}",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
        )
        print(task_id_list.tasks)
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Servers.Delete(context.TODO(),
                "{SERVER_ID}",
                cloud.GPUBaremetalClusterServerDeleteParams{
                    ClusterID: "{CLUSTER_ID}",
                    ProjectID: gcore.Int(projectID),
                    RegionID:  gcore.Int(regionID),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X DELETE \
          "https://api.gcore.com/cloud/v1/ai/clusters/gpu/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/{CLUSTER_ID}/node/{SERVER_ID}" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>

    ## Delete a cluster

    <p>Deletes the cluster and all its nodes. Local NVMe storage is permanently erased. File shares and object storage remain intact. Pass `all_floating_ips=true` to release any floating IPs, and `all_reserved_fixed_ips=true` to release reserved fixed IPs.</p>

    <Warning>
      Cluster deletion is irreversible. Data on local NVMe storage cannot be recovered.
    </Warning>

    <Tabs>
      <Tab title="Python SDK">
        ```python theme={null}
        import os
        from gcore import Gcore

        client = Gcore(api_key=os.environ.get("GCORE_API_KEY"))

        task_id_list = client.cloud.gpu_baremetal.clusters.delete(
            cluster_id="{CLUSTER_ID}",
            project_id=int(os.environ["GCORE_CLOUD_PROJECT_ID"]),
            region_id=int(os.environ["GCORE_CLOUD_REGION_ID"]),
            all_floating_ips=True,
            all_reserved_fixed_ips=True,
        )
        print(task_id_list.tasks)
        ```
      </Tab>

      <Tab title="Go SDK">
        ```go theme={null}
        package main

        import (
            "context"
            "fmt"
            "os"
            "strconv"

            "github.com/G-Core/gcore-go"
            "github.com/G-Core/gcore-go/cloud"
            "github.com/G-Core/gcore-go/option"
        )

        func main() {
            projectID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_PROJECT_ID"), 10, 64)
            regionID, _ := strconv.ParseInt(os.Getenv("GCORE_CLOUD_REGION_ID"), 10, 64)

            client := gcore.NewClient(option.WithAPIKey(os.Getenv("GCORE_API_KEY")))

            taskIDList, err := client.Cloud.GPUBaremetal.Clusters.Delete(context.TODO(),
                "{CLUSTER_ID}",
                cloud.GPUBaremetalClusterDeleteParams{
                    ProjectID:           gcore.Int(projectID),
                    RegionID:            gcore.Int(regionID),
                    AllFloatingIPs:      gcore.Bool(true),
                    AllReservedFixedIPs: gcore.Bool(true),
                })
            if err != nil {
                panic(err)
            }
            fmt.Printf("%+v\n", taskIDList.Tasks)
        }
        ```
      </Tab>

      <Tab title="curl">
        ```bash theme={null}
        curl -X DELETE \
          "https://api.gcore.com/cloud/v3/gpu/baremetal/${GCORE_CLOUD_PROJECT_ID}/${GCORE_CLOUD_REGION_ID}/clusters/{CLUSTER_ID}?all_floating_ips=true&all_reserved_fixed_ips=true" \
          -H "Authorization: APIKey ${GCORE_API_KEY}"
        ```

        Response:

        ```json theme={null}
        { "tasks": ["task-uuid"] }
        ```
      </Tab>
    </Tabs>
  </MethodSection>
</MethodSwitch>
