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

# Interfaces

> A NIC with its own identity — what it keeps across a detach, and where attachment actually happens.

An interface is a NIC with a MAC, an `addresses` array, and its own
[security-group membership](/networking/security-groups).

<Tabs>
  <Tab title="Console">
    Go to **Networking → Interfaces** and choose **Create Interface**. Under
    **Interface**, pick the **VPC** and **Subnet** and give it a **Name**.
    Leave **IP Address** and **MAC Address** under **Addressing** blank to
    have them assigned.

    A new interface belongs to no security group, which means it drops
    everything. Attach one from the interface's own page before you expect
    traffic — see [security groups](/networking/security-groups).
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST /v1/interfaces
    { "subnet": "7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d", "name": "web-eth0" }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic network interface create --subnet <subnet-id> --name web-eth0
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    ifc, err := network.New(cfg).CreateInterface(ctx, &network.InterfaceCreateRequest{
        Subnet: subnetID,
        Name:     "web-eth0",
    })
    ```
  </Tab>
</Tabs>

Interface responses embed `subnet`, including its VPC and nullable route-table
summary. Read `subnet.id` and `subnet.name` for the subnet, and
`subnet.vpc.id` and `subnet.vpc.name` for its VPC. The former `subnet_id` and
`vpc_id` response fields are no longer returned. In the Go SDK these are
`ifc.Subnet` and `ifc.Subnet.VPC`.

Creation still takes a `subnet` string reference, not a subnet object. Use the
embedded subnet's ID when copying placement into a new request. See
[subnet placement](/networking/subnets#reading-placement) for handling a null
route-table summary.

The platform assigns addresses and `mac` when omitted. `name` is unique per
subnet; addresses cannot overlap another allocation in the subnet. Subnet and
MAC are immutable. Patch `description` and `tags` on the interface, and manage
addresses through its `/addresses` collection.

## Reading addresses

The interfaces table shows **Private IPv4**, **Public IPv4**, and **IPv6**,
using the primary address in each family. An attached IPv6 floating IP takes
precedence over the directly attached IPv6 address. Open an interface's
**Addresses** tab for the full address table, including prefixes, primary or
secondary roles, and attached floating IPs.

Each directly attached address has a stable `id`, `family`, `address`,
`prefix`, `primary`, and `floating_ips` array. Address IDs identify children
of the interface; they do not have separate CRNs. Floating IP summaries include
both `id` and `crn` because floating IPs are independently managed resources.

```json theme={null}
{
  "addresses": [
    {
      "id": "b597657e-c9c2-49f4-bd8f-5d533d1093df",
      "family": "ipv4",
      "address": "10.0.1.10",
      "prefix": "10.0.1.10/32",
      "primary": true,
      "floating_ips": [
        {
          "id": "b2fabf44-11f0-44f7-bb0f-97b6c3744d64",
          "crn": "crn:network:sa-saopaulo-1:my-account:floating-ip/b2fabf44-11f0-44f7-bb0f-97b6c3744d64",
          "visibility": "public",
          "address": "198.51.100.10"
        }
      ]
    },
    {
      "id": "473a3497-9de6-4418-81bd-ad8d37f09f70",
      "family": "ipv6",
      "address": "2001:db8:1234:1:abcd:1234::",
      "prefix": "2001:db8:1234:1:abcd:1234::/96",
      "primary": true,
      "floating_ips": []
    }
  ]
}
```

The IPv4 `/32` identifies the owned address; it is not the guest's subnet mask.
IPv6 reserves a `/96` for the NIC and supplies its first `/128` through DHCPv6.
The rest of that `/96` is routed to the same NIC. Configuring extra addresses
inside it is the guest's responsibility. The initial limit is one IPv4 and one
IPv6 address entry per NIC; the array does not imply secondary-address support.

Floating IPs translate to the corresponding directly attached address. They
are not configured inside the guest. Each family can have one public and one
private FIP attached. There is no separate ordinary public IPv4 address.

Instances do not return IP summary fields. Read their NIC collection and then
`addresses`, including each entry's `floating_ips`.

## Adding IPv6 later

Enable IPv6 on the VPC, then the subnet. Every existing interface in that
subnet receives IPv6 automatically, and every new interface inherits all of
the subnet's enabled families. IPv4 addresses and existing address IDs stay
unchanged. The console provides **Enable IPv6** on VPC and subnet detail pages.

Read allocations with `GET /v1/interfaces/{interface_id}/addresses`. The address
collection also exposes create and delete operations, but the current limit
is one primary address per enabled family. Adding another address returns a
capacity conflict. Removing either required primary address returns `409`.
See [enabling subnet IPv6](/networking/subnets#enabling-ipv6-later) for routing
and security-group options.

A guest agent is not required. The guest operating system must run DHCPv6;
an existing guest might need its network configuration renewed or restarted
after IPv6 is enabled. DHCPv6 does not guarantee that every guest reacts
immediately to a newly available family.

An interface exists on its own. It is not a child of an instance, and it keeps
its address, its MAC and its security groups whether or not anything is
currently using it.

## Attaching an interface to an instance

Attachment happens on the [compute](/compute) side, not here:

<Tabs>
  <Tab title="Console">
    Open the instance under **Compute → Instances** and choose **Attach NIC**.
    Select a standalone interface under **Interface**. It keeps its address,
    MAC, and security groups. Use the selector's create action to create an
    interface first if needed, then return and select it.

    Confirm with **Attach interface**. The instance's **Networking** tab lists
    what is attached.
  </Tab>

  <Tab title="API">
    ```bash theme={null}
    POST /v1/instances/{instance_id}/nics
    { "interface": "7a1c9d3e-2f5b-4c8a-9e6d-3b2a1c4f5e8d" }
    ```
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    basaltic compute instance attach-nic <instance-id> \
      --interface <interface-id>
    ```

    The interface must already exist; attachment does not provision a NIC.
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    nic, err := compute.New(cfg).AttachInstanceNIC(ctx, instanceID,
        &compute.AttachInstanceNICRequest{
            Interface: interfaceID,
        })
    ```

    Attachment lives on the compute client, not network — the binding belongs
    to the instance.
  </Tab>
</Tabs>

An interface you created brings its own address, MAC and security groups, so
per-NIC overrides on that call are rejected rather than silently ignored. The
attach endpoint takes an existing interface. Create one first when needed.

The difference shows up at detach:

<Tabs>
  <Tab title="Interface you created">
    Detaching returns it to standalone. The interface, its address and its
    security-group membership all survive, ready to attach somewhere else.
  </Tab>

  <Tab title="NIC compute provisioned">
    Detaching tears it down. Compute destroys the NICs it created; the address
    goes back to the subnet.
  </Tab>
</Tabs>

<Warning>
  `DELETE /v1/interfaces/{interface_id}` refuses while an instance or a floating
  IP holds the interface. Detach it from the instance and detach any floating
  IP before deleting it. Stopped instances still hold their interfaces.
</Warning>

<Note>
  The `attached_to` field contains the owning instance's UUID, or null when
  no instance holds the interface. It reflects the instance's NIC binding,
  including while the instance is stopped. Floating IP attachment is separate.
</Note>
