# Host (glue) records

> Create, update and delete host (glue) records for name servers that live under the domain they serve, and the two registry models behind them.

A **host record** is needed when you run a name server that lives under the domain it serves — `ns1.apiname.com` answering for `apiname.com`. Resolvers cannot look that up without a circular dependency, so the registry publishes its IP addresses as *glue*.

:::note[You probably do not need these]
Host records are only for running your own name servers under the domain. If you point at a third party's name servers, or at `tr.apiname.com` / `eu.apiname.com`, you need no host records at all.
:::

Two terms you will meet in the errors:

- **In-bailiwick** — the host name is a subdomain of the domain it serves. Most registries only accept glue for in-bailiwick hosts. Anything else gives `Dna.DomainService:Dns:10019`.
- **Host object support** — registries differ in how they model name servers. The catalogue field `isHostObjectAccepted` tells you, and `isGlueRecordAllowed` says whether glue is accepted at all.

## The two models, and why it matters to you

There are two ways a registry can represent a name server that lives under your domain. Which one applies changes what you get back from `GET /domains/info`, so it is worth understanding before you build a UI around it.

| `isHostObjectAccepted` | What happens to `ns1.apiname.com` |
| --- | --- |
| **true** | It becomes a **host object** — an independent record at the registry with its own name and IP addresses. It can be created, renamed, re-addressed and deleted on its own, and it can be shared by several domains. |
| **false** | **No host object is created.** The name server stays attached to the domain as a **glue record**: the name and its IP travel with the domain's own record rather than existing separately. |

:::note[Where you will see each]
`.tr` and `.ge` are typical examples of registries where `isHostObjectAccepted` is **false** — your child name server never appears as a standalone host, only as a glue record on the domain.

An extension may support **both** models. When it does, **the host object takes priority** — we create the host object and manage the name server through it.
:::

:::caution[What this changes in practice]
- **When `isHostObjectAccepted` is true**, the host endpoints below behave exactly as described: create once, reuse across domains, delete when no longer referenced.
- **When it is false**, the host is not an independent object, so there is nothing to share between domains and nothing to delete separately. Removing the name server from the domain's delegation removes the glue with it. Each domain carries its own copy of the name and IP.
- **Do not assume a host you created on one domain is visible on another** unless the extension uses host objects. Read `isHostObjectAccepted` from the catalogue rather than assuming.

If neither model is available for an extension, you get `Dna.DomainService:Dns:10018` — "A valid host type could not be determined for this TLD".
:::

## POST /api/v1/domains/dns/host

Creates a host record with its IP addresses.

**Request**

```json
{
  "domainName": "apiname.com",
  "hostName": "ns1.apiname.com",
  "ipAddresses": [
    { "ipAddress": "203.0.113.10", "ipVersion": "v4" },
    { "ipAddress": "2001:db8::10", "ipVersion": "v6" }
  ]
}
```

| Field | Required | Notes |
| --- | --- | --- |
| `domainName` | required | Maximum 63 characters. |
| `hostName` | required | Full host name, maximum 100 characters. Normally must be a subdomain of `domainName`. |
| `ipAddresses` | required | At least one. No duplicates. |
| `ipAddresses[].ipAddress` | required | IPv4 or IPv6 literal. |
| `ipAddresses[].ipVersion` | required | `v4` or `v6`. Case does not matter. |

**Response — 204, no body**

:::tip[The order to do this in]
1. `POST /domains/dns/host` — create `ns1.apiname.com` with its IP.
2. Repeat for `ns2.apiname.com`.
3. `PUT /domains/dns/name-server` — delegate the domain to them.

Doing it the other way round fails with `Dna.DomainService:Dns:10016`, because the delegation needs the glue to exist first.
:::

## PUT /api/v1/domains/dns/host · DELETE /api/v1/domains/dns/host

Rename a host and/or replace its IP addresses, or delete it.

**PUT — change the IP addresses**

```json
{
  "domainName": "apiname.com",
  "hostName": "ns1.apiname.com",
  "ipAddresses": [
    { "ipAddress": "203.0.113.20", "ipVersion": "v4" }
  ]
}
```

**PUT — rename and re-address in one call**

```json
{
  "domainName": "apiname.com",
  "hostName": "ns1.apiname.com",
  "newHostName": "dns1.apiname.com",
  "ipAddresses": [
    { "ipAddress": "203.0.113.20", "ipVersion": "v4" }
  ]
}
```

`ipAddresses` is the **complete replacement set**. Omit `newHostName` to keep the current name.

**DELETE**

```json
{
  "domainName": "apiname.com",
  "hostName": "ns1.apiname.com"
}
```

**Response — 204, no body**

:::caution[A host in use cannot be deleted]
If the host is still serving as a name server — for this domain or any other — deletion is refused with `Dna.DomainService:Dns:10024`. Re-delegate the affected domains with `PUT /domains/dns/name-server` first, then delete the host.
:::

**Errors — all host endpoints**

| Code | Meaning and fix |
| --- | --- |
| `Dna.DomainService:Domain:10044` | Invalid domain or host name. |
| `Dna.DomainService:Domain:10007` | Domain not found or not yours. |
| `Dna.DomainService:Domain:10016` | The domain is not active. |
| `Dna.DomainService:Domain:10070` | Waiting for registry documents. |
| `Dna.DomainService:Dns:10015` | The same IP appears twice in `ipAddresses`. |
| `Dna.DomainService:Dns:10006` | `ipAddresses` is empty. |
| `Dna.DomainService:Dns:10007` | Malformed IPv4 address. |
| `Dna.DomainService:Dns:10008` | Malformed IPv6 address. |
| `Dna.DomainService:Dns:10014` | `ipVersion` is not `v4` or `v6`. |
| `Dna.DomainService:Dns:10026` | This TLD does not accept IPv6 glue. Send only v4. |
| `Dna.DomainService:Dns:10012` | `hostName` is empty. |
| `Dna.DomainService:Dns:10019` | The host is not a subdomain of the domain (not in-bailiwick). |
| `Dna.DomainService:Dns:10018` | We could not determine how this TLD models name servers. Open a ticket. |
| `Dna.DomainService:Dns:10021` | Create: the host already exists on this domain. |
| `Dna.DomainService:Dns:10020 / :10004` | Edit or delete: the host does not exist. |
| `Dna.DomainService:Dns:10017` | Glue records are not allowed for this TLD. |
| `Dna.DomainService:Dns:10023 / :10024` | The host cannot be deleted in its current state, or is still in use. |
| `Dna.DomainService:Domain:Dns:Host:10001` | Registry-side host conflict. |
| `Dna.DomainService:Domain:Dns:Host:10002` | The registry does not know this host. |
