Docs / Metadata

Working with metadata

Pools, subnets, and addresses can all carry your own key/value tags. nxip stores them and hands them back untouched - it's somewhere to keep the context your other tools already own, next to the address space it belongs to.

What it's for

An IPAM record on its own tells you a block exists. It doesn't tell you which VPC it ended up in, which team pays for it, or which ticket asked for it. Metadata is where that goes, so the answer travels with the record instead of living in a spreadsheet next to it.

Typical keys: vpc_id, cost_center, owner, ticket, cluster. There's no schema and no registry - if your systems agree on a key, it works.

Setting it

Pass metadata when you create a resource, or PATCH it later.

curl -X POST https://nxip.dev/v1/subnets \
  -H "x-api-key: $NXIP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "environment": "production",
    "region": "us-east-1",
    "family": "IPV4",
    "prefixLength": 24,
    "metadata": {
      "vpc_id": "vpc-0a1b2c3d",
      "cost_center": "cc-4417"
    }
  }'

In Terraform it's a plain map on the resource:

resource "nxip_subnet" "payments" {
  environment   = "production"
  region        = "us-east-1"
  family        = "IPV4"
  prefix_length = 24

  metadata = {
    vpc_id      = "vpc-0a1b2c3d"
    cost_center = "cc-4417"
  }
}

Or edit it in the dashboard, which has a key/value editor on pools and subnets.

Updates replace, they don't merge

A PATCH sets the whole object. Whatever you send becomes the resource's entire metadata, and any key you leave out is dropped. If you mean to keep the existing keys, send them back along with the new ones.

# subnet currently has { "vpc_id": "vpc-0a1b2c3d", "cost_center": "cc-4417" }

curl -X PATCH https://nxip.dev/v1/subnets/$SUBNET_ID \
  -H "x-api-key: $NXIP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "metadata": { "owner": "platform-team" } }'

# it now has just { "owner": "platform-team" } - the other two are gone

This is deliberate: a merge has no way to express deleting a key, and "send the state you want" matches how the rest of nxip behaves. Terraform handles it for you - the map in your config is the state you want, so it converges either way.

An empty object ({}) is valid and clears everything.

Editing metadata doesn't touch the address space

Metadata updates in place. The resource keeps its ID and its allocated block, and anything carved out of it is untouched - tagging a pool doesn't disturb the subnets inside it, and tagging a subnet doesn't disturb its addresses.

The same is true of a subnet's name and description, which are also editable. In Terraform, changing any of these shows as an ordinary update in the plan, not a replace.

Putting a pool on the map

The dashboard's map plots every pool geographically. Most place themselves: if a pool's region is a recognized cloud region (eu-west-2, uksouth, us-east-1, and so on, across AWS, Azure, and GCP), nxip already knows roughly where that is.

On-prem sites don't have a standard region code. region is a free-form string, so a pool tagged dc-manchester matches nothing - set latitude and longitude on the pool and it plots exactly where you put it.

resource "nxip_pool" "manchester" {
  name        = "dc-manchester"
  cidr        = "10.40.0.0/16"
  family      = "IPV4"
  environment = "production"
  region      = "dc-manchester"

  metadata = {
    latitude  = "53.4808"
    longitude = "-2.2426"
  }
}

Both are strings, like every other metadata value, and both have to be present and parse as numbers in range. An explicit pair always wins over the region lookup, so you can use it to correct a cloud pool's position too. A pool that can't be placed either way isn't hidden - it's listed under the map with a control to set its location.

These two keys are the only metadata nxip itself reads. Everything else is stored and returned, never interpreted.

Limits

Flat across every plan, not a paid upgrade:

  • 20 keys per resource
  • 128 characters per key
  • 256 characters per value

Keys and values are both strings. Numbers and booleans need quoting - that's why the coordinates above are "53.4808" and not 53.4808. A write that breaks any of these is rejected with a 400 naming the problem.

The bounds match what cloud providers already use for resource tags, so anything that fits AWS tags fits here. They're generous for real use and tight enough that metadata can't quietly become a storage bill.

Full request and response shapes are in the API reference. For how metadata sits alongside the rest of the model, see pools, subnets & hierarchy.