Docs / Concepts
Pools, subnets, and how nesting works
Three ideas cover the whole model: pools are top-level blocks, subnets are carved from them and can nest, and addresses are only ever recorded when something actually claims one.
Pools
A pool is a top-level CIDR block: the parent range everything else carves subnets from. A pool is scoped to exactly one environment, region, and address family (IPv4 or IPv6). To support both families in the same environment/region, create two pools, not one mixed-family pool.
Subnets, and how they nest
A subnet request either auto-resolves or nests explicitly:
Auto-resolve: supply environment/region/family, and nxip routes to the matching pool. If a top-level subnet in that pool is tagged with a kind (a free-text label like "region" or "vpc"), new requests land under it automatically. The same request works whether or not that structure has been built yet.
Explicit nesting: supply parentSubnetId directly to attach under a specific subnet, bypassing auto-resolution. This is the deliberate path for structure auto-resolution can't disambiguate, like splitting a team's subnet across two availability zones.
Addresses are sparse
An address row only exists once something is explicitly registered as ACTIVE or RESERVED. nxip never materializes a row for every possible address in a subnet (a /64 has 264 of them). Absence of a row means the address is available.
Metadata
Pools, subnets, and addresses can all carry free-form key/value tags, like vpc_id or cost_center, or whatever your own systems track, stored and returned exactly as sent. nxip doesn't interpret it; it's there so the tools that already own that context can read it straight from the record.
The one exception is latitude and longitude on a pool, which the dashboard reads to place that pool on the world map. Everything else is yours. See working with metadata for the limits, the update semantics, and how to set it from Terraform.
What can change, and what blocks deletion
The fields that define a resource are immutable: cidr, family, environment, region, and so on. Changing one means deleting the old resource and creating a new one, not editing it.
The descriptive fields aren't. A subnet's name and description, and metadata on pools, subnets, and addresses, all update in place over PATCH. The resource keeps its ID and its allocated block, and everything carved out of it stays exactly where it is - renaming a subnet is just a rename, it doesn't release the CIDR or disturb a single address inside it.
A pool or subnet refuses deletion while it still has children carved from it - the API returns a clear error asking you to remove those first, rather than silently orphaning address space something else still depends on.
Managing this with Terraform: editing a name, description, or metadata shows as an ordinary in-place update. Changing an immutable field forces a replace, and the plan won't warn you if the resource still has children - Terraform's graph only knows about the connections your own config makes explicit (like parentSubnetId), not the ones nxip resolves for you automatically. If a replace's delete step gets blocked this way, nothing is lost: the create step never runs, so the original resource is left exactly as it was. Two related cases Terraform does handle cleanly on its own: destroying a whole subtree in one command (children are removed before their parent, once the nesting is explicit), and noticing a resource was removed entirely outside Terraform - the next plan shows a normal create, not an error.
See this in practice in Getting started, or manage it declaratively with the Terraform provider.
