---
title: "Attach floating IP to VM"
method: POST
path: "/api/v1/vms/{id}/ip"
tags: ["Networking"]
---

# Attach floating IP to VM

`POST /api/v1/vms/{id}/ip`

Attach a floating public IP to a virtual machine. Pick **one** of two modes:

## Option A — attach a reserved IP (use `ip_id`)

Pass `ip_id` set to a previously reserved IP (from `POST /api/v1/ips/reserve` or `GET /api/v1/ips?reserved=true`). The IP must:
- belong to the same account
- not be currently attached to another VM
- have `reserved: true`

No new billing on attach — you're already paying for the reserved IP.

A VM can hold up to **4 public IPv4 addresses**. The first IPv4 on a VM becomes its primary address; additional IPv4s must be reserved IPs attached with `ip_id`.

## Option B — auto-assign a new IP (use `type`)

Leave `ip_id` empty and pass `type` to allocate a fresh IP from the pool:
- `type: IPv4` (default if omitted)
- `type: IPv6`

Auto-assign is available only while the VM has no public IP of that family, and the IP is included with the VM at no extra charge. It is not reserved: detaching releases it back to the shared pool.

## Notes

- Auto-assign (`type`) fails if the VM already has a public IP of the same family — attach a reserved IP (`ip_id`) to add more IPv4s, up to 4 total.
- Optionally pass `security_groups` (UUID array) to apply security groups to the new NIC.

## Path parameters

- `id` string, uuid, required

## Headers

- `X-Project-ID` string, uuid, required

## Request body

- AttachIPRequest — Provide **either** `ip_id` (attach an existing reserved IP) **or** `type` (auto-allocate a new IP). Don't combine — `ip_id` takes precedence and `type` is ignored when both are sent.
  - `ip_id` string, uuid — ID of a previously reserved IP. The IP must belong to the same account, be reserved, and not already attached to another VM. No new billing on attach — you're already paying for the reserved IP. Use this to add up to 4 public IPv4 addresses to a VM.
  - `type` 'IPv4' | 'IPv6' — IP family to auto-allocate. Used only when `ip_id` is omitted. Defaults to `IPv4`. Available only while the VM has no public IP of that family; the IP is included with the VM at no extra charge and is released back to the pool on detach.
  - `security_groups` string[] — Security group IDs (UUIDs) to apply to the new NIC.

## Response `200`

IP attached

- AttachIPResponse
  - `success` boolean, required
  - `message` string
  - `data` object
    - `vm_id` string, uuid — VM the IP was attached to.
    - `ip_address` string — The attached IP address.
    - `nic_id` integer — NIC identifier for this attachment. Use it when detaching.
    - `mac` string

## Other responses

- `400` — Invalid request parameters
- `401` — Authentication required
- `402` — Account balance is insufficient for this operation. Top up the balance and retry.
- `403` — Billing validation failed. The account is not in good standing. Check the `reason` field: - `banned` — account suspended - `failed` — last payment failed; top up the account balance - `no_billing_customer` — billing not set up
- `404` — Resource not found

---

[API](https://skmtc.dev/rafftechnologies/apis/raff-api.md) · [All operations](https://skmtc.dev/rafftechnologies/apis/raff-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/rafftechnologies/raff-api/revisions/2f4df56be77c/schema)
