# dnsZones (/docs/reference/api/dns-zones)

> DNS zones on a provider account (DigitalOcean Domains first), with their [records](/docs/reference/api/dns-records). Every call records what the tenant wants and returns at once; the `vps.provider-resources` reconciler converges the provider through `ProviderImpl.dns`. Reading takes `compute:dns:read`, everything else `compute:dns:manage`, on `provider-dns-zone/{id}`. Zones book no quota (at most 50 per tenant) and do not bill.



DNS zones on a provider account (DigitalOcean Domains first), with their [records](/docs/reference/api/dns-records). Every call records what the tenant wants and returns at once; the `vps.provider-resources` reconciler converges the provider through `ProviderImpl.dns`. Reading takes `compute:dns:read`, everything else `compute:dns:manage`, on `provider-dns-zone/{id}`. Zones book no quota (at most 50 per tenant) and do not bill.

All 4 methods are served by @better-compute/server 0.3.0.

| Method              | Kind     | Authorization                                      | Phase | Status     |
| ------------------- | -------- | -------------------------------------------------- | ----- | ---------- |
| [`create`](#create) | mutation | `compute:dns:manage` @ `compute-provider-dns-zone` | v1.0  | registered |
| [`list`](#list)     | read     | `compute:dns:read` @ `compute-tenant` + items      | v1.0  | registered |
| [`get`](#get)       | read     | `compute:dns:read` @ `compute-provider-dns-zone`   | v1.0  | registered |
| [`delete`](#delete) | mutation | `compute:dns:manage` @ `compute-provider-dns-zone` | v1.0  | registered |

## create [#create]

`POST /api/compute/dnsZones/create`

Makes the zone for a domain (`zone`, lower case, without a final dot) and returns it `pending`. A domain has one live zone per provider account, so two tenants never share one: a second is `CONFLICT`, without saying whose it is, and so is a zone inside or above another tenant's (`shop.example.com` next to `example.com`), which the provider's shared name servers could answer for. A zone the account already holds and vps did not make goes to `error` unless the account's owner tenant adopts it with `adopt: true`; any other tenant asking to adopt is `ACCESS_DENIED` (reason `adoptNotOwner`). Publishes `providerDnsZone.created`, then `providerDnsZone.ready` or `providerDnsZone.error`.

* **Kind:** mutation
* **Authorization:** `compute:dns:manage` @ `compute-provider-dns-zone`
* **Module:** `vps`
* **Phase:** v1.0 (registered)

**Input**

| Field            | Type    | Required | Constraints                                                       |
| ---------------- | ------- | -------- | ----------------------------------------------------------------- |
| `tenantId`       | string  | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`        |
| `projectId`      | string  |          | at most 56 characters; matches `^prj_[0-9a-hjkmnp-tv-z]{26,52}$`  |
| `poolId`         | string  | yes      | at most 57 characters; matches `^pool_[0-9a-hjkmnp-tv-z]{26,52}$` |
| `zone`           | string  | yes      | at most 253 characters                                            |
| `adopt`          | boolean |          | default `false`                                                   |
| `idempotencyKey` | string  | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`        |

## list [#list]

`POST /api/compute/dnsZones/list`

Returns the tenant's zones in the order they were made (at most 1000), optionally of one pool or project. Deleted ones only with `includeDeleted`.

* **Kind:** read
* **Authorization:** `compute:dns:read` @ `compute-tenant` + items
* **Module:** `vps`
* **Phase:** v1.0 (registered)

**Input**

| Field            | Type    | Required | Constraints                                                       |
| ---------------- | ------- | -------- | ----------------------------------------------------------------- |
| `tenantId`       | string  | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`        |
| `poolId`         | string  |          | at most 57 characters; matches `^pool_[0-9a-hjkmnp-tv-z]{26,52}$` |
| `projectId`      | string  |          | at most 56 characters; matches `^prj_[0-9a-hjkmnp-tv-z]{26,52}$`  |
| `includeDeleted` | boolean |          | default `false`                                                   |

## get [#get]

`POST /api/compute/dnsZones/get`

Returns one zone: its domain, whether it was adopted, its state and, once the provider reported them, the `nameServers` the domain's registrar must delegate to.

* **Kind:** read
* **Authorization:** `compute:dns:read` @ `compute-provider-dns-zone`
* **Module:** `vps`
* **Phase:** v1.0 (registered)

**Input**

| Field      | Type   | Required | Constraints                                                      |
| ---------- | ------ | -------- | ---------------------------------------------------------------- |
| `tenantId` | string | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`       |
| `zoneId`   | string | yes      | at most 56 characters; matches `^pdz_[0-9a-hjkmnp-tv-z]{26,52}$` |

## delete [#delete]

`POST /api/compute/dnsZones/delete`

Marks the zone for deletion and returns it `deleting`; the reconciler deletes it at the provider and publishes `providerDnsZone.deleted`. A zone that still holds records is `INVALID_STATE` (reason `zoneNotEmpty`). An adopted zone is only forgotten: it was the account's before and stays at the provider.

* **Kind:** mutation
* **Authorization:** `compute:dns:manage` @ `compute-provider-dns-zone`
* **Module:** `vps`
* **Phase:** v1.0 (registered)

**Input**

| Field      | Type   | Required | Constraints                                                      |
| ---------- | ------ | -------- | ---------------------------------------------------------------- |
| `tenantId` | string | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`       |
| `zoneId`   | string | yes      | at most 56 characters; matches `^pdz_[0-9a-hjkmnp-tv-z]{26,52}$` |
