---
sidebar_label: Dimensions
doc_id: 8e27eb23-c551-49a1-919a-f747f8cd705d
description: >-
  User-defined key-value tags for nullplatform resources enabling semantic
  declaration and inheritance of configurations.
keywords:
  - dimensions
  - tagging
  - configuration management
  - nullplatform
  - scopes
---

# Dimensions and values

## What are dimensions and dimension values

Dimensions are user-defined key-value tags that can be attached to different nullplatform resources (in particular, scopes).
They’re used to declare the semantics of what you’re creating in business terms (for example, “this is a production resource” or 
“this is a testing resource”).

For example, a scope can have the dimension `environment` with dimension values such as `testing` or `production`.

## What are the benefits of using dimensions

Let's start with an example. If you associate the `DB_PASSWORD` parameter to a testing scope, whenever you need to create
another testing scope, you will have to ask for the password again and create a new parameter value for that scope. If
you're labeling the scope's `environment` dimension as `testing`, you just need to set the parameter once for the `testing`
dimension and any scope that's labeled as `testing` will receive it. This is an example on how **dimensions are a way of declaring the semantics** of what we're creating.

The same thing happens with approvals. If you want to declare that everything that's production will require an approval,
then you'll set the approval action for the right dimension (let's say it's again `environment` and the dimension 
value is `production`) and it will instantly apply to all scopes labeled that way.

## Which entities support dimensions

At this time, the entities that support dimensions, either to label resources or to act based on dimensions are:

- Scopes
- Parameters
- Runtime Configurations
- Approvals
- Services

## Creating dimensions and values

**Dimensions are user-defined**. This means that we do not bundle nullplatform with a predefined set of dimensions and
it's completely up to you to set them. While our examples are a lot about environments, it's very common to create dimensions
for other criteria such as the country or geography where the business operates.

**Be careful with adding many dimensions**. All dimensions that you create will have to be selected by developers
whenever they create a resource such as a scope and this can hurt developer experience. Be mindful of creating
dimensions that are useful for your business needs.

**Dimensions and values are created at a specific NRN**. When you create your dimension (e.g., environment, country, ...)
you have to specify the NRN level at which they will be available (specifying at a certain level automatically makes it
available for all of its children). You can make dimension values (eg: development, UK, ...) available at lower levels.

**You can have the same dimensions in sibling NRNs but never in a parent-child**. It's ok to have the `environment`
dimension defined at the NRN `organization=1:account=2` and also at `organization=1:account=3` but it's not possible
to have it defined also at the NRN `organization=1:account=2:namespace=3`.

**You need ops permissions to alter dimensions**. Creating, modifying, or deleting dimensions can have huge impact on
the underlying infrastructure so changing them requires an `ops` role.

## API examples

While the complete API is published in the API section of this site, these are some example API calls that you might 
find useful:

### Creating a dimension and a value

```http
POST /dimension
{
  "nrn": "organization=1",
  "name": "Environment",
  "order": 1
}
```

```http
POST /dimension/1/value
{
  "nrn": "organization=1",
  "name": "Development"
}
```

### Getting a dimension or a value

```
GET /dimension/1
{
  "id": 1,
  "name": "Environment",
  "nrn": "organization=1234",
  "slug": "environment",
  "status": "active",
  "order": 1
}
```

```
GET /dimension/value/1
{
  "id": 1,
  "name": "Dev",
  "nrn": "organization=1:account=2:namespace=3",
  "slug": "dev",
  "status": "active"
}
```

### List dimensions that apply at a certain NRN (scanning parent NRN nodes but not children)
```
GET /dimension?nrn=organization=1:account=2
{
  "paging": {
    "offset": 0,
    "limit": 30
  },
  "results": [
    {
      "id": 1234,
      "name": "environment",
      "nrn": "organization=1",
      "slug": "environment",
      "status": "active",
      "order": 1,
      "values": [
        {
          "id": 1,
          "name": "testing",
          "slug": "testing",
          "nrn": "organization=1",
          "status": "active",
          "created_at": "2024-03-15T13:26:19.592Z",
          "updated_at": "2024-03-15T13:26:19.592Z"
        },
        {
          "id": 2,
          "name": "production",
          "slug": "production",
          "nrn": "organization=1",
          "status": "active",
          "created_at": "2024-03-15T13:26:19.592Z",
          "updated_at": "2024-03-15T13:26:19.592Z"
        }
      ]
    }
  ]
}
```

### List dimensions that apply at or below a certain NRN (scanning children nodes)
```
GET /dimension?nrn=organization=1:account=*
{
  "paging": {
    "offset": 0,
    "limit": 30
  },
  "results": [
    {
      "id": 1234,
      "name": "environment",
      "nrn": "organization=1:account=2",
      "slug": "environment",
      "status": "active",
      "order": 1,
      "values": [
        {
          "id": 1,
          "name": "testing",
          "slug": "testing",
          "nrn": "organization=1:account=2",
          "status": "active",
          "created_at": "2024-03-15T13:26:19.592Z",
          "updated_at": "2024-03-15T13:26:19.592Z"
        },
        {
          "id": 2,
          "name": "production",
          "slug": "production",
          "nrn": "organization=1:account=2",
          "status": "active",
          "created_at": "2024-03-15T13:26:19.592Z",
          "updated_at": "2024-03-15T13:26:19.592Z"
        }
      ]
    },
     {
      "id": 2345,
      "name": "environment",
      "nrn": "organization=1:account=3",
      "slug": "environment",
      "status": "active",
      "order": 1,
      "values": [
        {
          "id": 1,
          "name": "development",
          "slug": "development",
          "nrn": "organization=1:account=3",
          "status": "active",
          "created_at": "2024-03-15T13:26:19.592Z",
          "updated_at": "2024-03-15T13:26:19.592Z"
        },
        {
          "id": 2,
          "name": "production",
          "slug": "production",
          "nrn": "organization=1:account=3",
          "status": "active",
          "created_at": "2024-03-15T13:26:19.592Z",
          "updated_at": "2024-03-15T13:26:19.592Z"
        }
      ]
    }
  ]
}
```

### List dimension values

The calls are exactly the same that you'll do for dimensions, replacing `/dimension` for `/dimension/value`. Here are
some examples:

```
GET /dimension/value?nrn=organization=1:account=2
{
  "paging": {
    "offset": 0,
    "limit": 30
  },
  "results": [
    {
      "id": 2345,
      "name": "Dev",
      "nrn": "organization=1:account=2",
      "slug": "dev",
      "status": "active"
    },
    ...
  ]
}
```

```
GET /dimension/value?nrn=organization=1:account=*
{
  "paging": {
    "offset": 0,
    "limit": 30
  },
  "results": [
    {
      "id": 2345,
      "name": "Dev",
      "nrn": "organization=1:account=2",
      "slug": "dev",
      "status": "active"
    },
    {
      "id": 2345,
      "name": "Prod",
      "nrn": "organization=1:account=2",
      "slug": "dev",
      "status": "active"
    },
    {
      "id": 2345,
      "name": "Test",
      "nrn": "organization=1:account=3",
      "slug": "dev",
      "status": "active"
    },
    {
      "id": 2345,
      "name": "Production",
      "nrn": "organization=1:account=3",
      "slug": "dev",
      "status": "active"
    },
    ...
  ]
}
```
