# Nameservers

Read and set a domain's nameservers, and register, modify, or delete child (glue) nameservers.

Manage the nameservers on a domain: read the current set, replace it, and register, modify, or delete child (glue) nameservers hosted under the domain.

## Get nameservers

Return the nameservers currently set on a domain.

`GET /domains/{domain}/nameservers`

### Parameters

<ParamField path="domain" type="text" required>
  The domain to read, for example `example.com`.
</ParamField>

### Request

<CodeGroup>
```bash cURL
API_KEY="your-api-key"
EMAIL="you@example.com"
ENDPOINT="https://portal.hostraha.com/modules/addons/DomainsReseller/api/index.php"
TS=$(date -u +"%y-%m-%d %H")
TOKEN=$(printf '%s' "$API_KEY" \
  | openssl dgst -sha256 -hmac "$EMAIL:$TS" -hex \
  | sed 's/^.*= //' | tr -d '\n' | base64 -w0)
curl -s "$ENDPOINT/domains/example.com/nameservers" \
  -H "username: $EMAIL" \
  -H "token: $TOKEN"
```

```php PHP
<?php
$apiKey   = "your-api-key";
$email    = "you@example.com";
$endpoint = "https://portal.hostraha.com/modules/addons/DomainsReseller/api/index.php";

$token = base64_encode(hash_hmac("sha256", $apiKey, "{$email}:" . gmdate("y-m-d H")));

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "{$endpoint}/domains/example.com/nameservers");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    "username: {$email}",
    "token: {$token}",
]);
echo curl_exec($curl);
curl_close($curl);
```

```python Python
from datetime import datetime, timezone

API_KEY  = "your-api-key"
EMAIL    = "you@example.com"
ENDPOINT = "https://portal.hostraha.com/modules/addons/DomainsReseller/api/index.php"

def token() -> str:
    ts = datetime.now(timezone.utc).strftime("%y-%m-%d %H")
    digest = hmac.new(f"{EMAIL}:{ts}".encode(), API_KEY.encode(), hashlib.sha256).hexdigest()
    return base64.b64encode(digest.encode()).decode()

resp = requests.get(f"{ENDPOINT}/domains/example.com/nameservers",
                    headers={"username": EMAIL, "token": token()})
print(resp.json())
```

```javascript Node.js

const API_KEY  = "your-api-key";
const EMAIL    = "you@example.com";
const ENDPOINT = "https://portal.hostraha.com/modules/addons/DomainsReseller/api/index.php";

function token() {
  const ts = new Date().toISOString().slice(2, 13).replace("T", " "); // "yy-mm-dd HH" UTC
  const digest = crypto.createHmac("sha256", `${EMAIL}:${ts}`).update(API_KEY).digest("hex");
  return Buffer.from(digest, "utf8").toString("base64");
}

const res = await fetch(`${ENDPOINT}/domains/example.com/nameservers`, {
  headers: { username: EMAIL, token: token() },
});
console.log(await res.json());
```

```go Go
package main

	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"io"
	"net/http"
	"time"
)

const (
	apiKey   = "your-api-key"
	email    = "you@example.com"
	endpoint = "https://portal.hostraha.com/modules/addons/DomainsReseller/api/index.php"
)

func token() string {
	ts := time.Now().UTC().Format("06-01-02 15") // yy-mm-dd HH
	mac := hmac.New(sha256.New, []byte(email+":"+ts))
	mac.Write([]byte(apiKey))
	return base64.StdEncoding.EncodeToString([]byte(hex.EncodeToString(mac.Sum(nil))))
}

func main() {
	req, _ := http.NewRequest("GET", endpoint+"/domains/example.com/nameservers", nil)
	req.Header.Set("username", email)
	req.Header.Set("token", token())
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
```
</CodeGroup>

### Response

```json
{"status":"success","message":"","success":"success"}
```

## Save nameservers

Replace the nameservers on a domain. Provide at least `ns1` and `ns2`; `ns3` through `ns5` are optional.

`POST /domains/{domain}/nameservers`

### Parameters

<ParamField path="domain" type="text" required>
  The domain to update, for example `example.com`.
</ParamField>
<ParamField body="ns1" type="text" required>
  Primary nameserver hostname.
</ParamField>
<ParamField body="ns2" type="text" required>
  Secondary nameserver hostname.
</ParamField>
<ParamField body="ns3" type="text">
  Third nameserver hostname.
</ParamField>
<ParamField body="ns4" type="text">
  Fourth nameserver hostname.
</ParamField>
<ParamField body="ns5" type="text">
  Fifth nameserver hostname.
</ParamField>

### Request

<CodeGroup>
```bash cURL
curl -s "$ENDPOINT/domains/example.com/nameservers" \
  -H "username: $EMAIL" \
  -H "token: $TOKEN" \
  --data "ns1=ns1.hostraha.com" \
  --data "ns2=ns2.hostraha.com"
```

```php PHP
<?php
// Reuse the auth setup from the get example above.
$fields = http_build_query([
    "ns1" => "ns1.hostraha.com",
    "ns2" => "ns2.hostraha.com",
]);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "{$endpoint}/domains/example.com/nameservers");
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $fields);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, [
    "username: {$email}",
    "token: {$token}",
]);
echo curl_exec($curl);
curl_close($curl);
```

```python Python
resp = requests.post(f"{ENDPOINT}/domains/example.com/nameservers",
                     headers={"username": EMAIL, "token": token()},
                     data={"ns1": "ns1.hostraha.com", "ns2": "ns2.hostraha.com"})
print(resp.json())
```

```javascript Node.js
const body = new URLSearchParams({
  ns1: "ns1.hostraha.com",
  ns2: "ns2.hostraha.com",
});

const res = await fetch(`${ENDPOINT}/domains/example.com/nameservers`, {
  method: "POST",
  headers: { username: EMAIL, token: token() },
  body,
});
console.log(await res.json());
```

```go Go
form := url.Values{}
form.Set("ns1", "ns1.hostraha.com")
form.Set("ns2", "ns2.hostraha.com")

req, _ := http.NewRequest("POST", endpoint+"/domains/example.com/nameservers", strings.NewReader(form.Encode()))
req.Header.Set("username", email)
req.Header.Set("token", token())
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
```
</CodeGroup>

<Note>
  The Go and Node.js save snippets reuse the `token()` helper and imports from the get example. Go also needs `net/url` and `strings`.
</Note>

### Response

```json
{"success":true}
```

<ResponseField name="success" type="boolean">
  `true` when the nameservers are saved.
</ResponseField>

## Register a child nameserver

Register a child (glue) nameserver hosted under this domain, for example `ns1.example.com`, and point it at an IP address.

`POST /domains/{domain}/nameservers/register`

### Parameters

<ParamField path="domain" type="text" required>
  The parent domain, for example `example.com`.
</ParamField>
<ParamField body="nameserver" type="text" required>
  The child nameserver hostname to register, for example `ns1.example.com`.
</ParamField>
<ParamField body="ipaddress" type="text" required>
  The IP address the nameserver resolves to.
</ParamField>

### Request

<CodeGroup>
```bash cURL
curl -s "$ENDPOINT/domains/example.com/nameservers/register" \
  -H "username: $EMAIL" \
  -H "token: $TOKEN" \
  --data "nameserver=ns1.example.com" \
  --data "ipaddress=192.0.2.1"
```

```python Python
resp = requests.post(f"{ENDPOINT}/domains/example.com/nameservers/register",
                     headers={"username": EMAIL, "token": token()},
                     data={"nameserver": "ns1.example.com", "ipaddress": "192.0.2.1"})
print(resp.json())
```
</CodeGroup>

## Modify a child nameserver

Change the IP address of an existing child nameserver.

`POST /domains/{domain}/nameservers/modify`

### Parameters

<ParamField path="domain" type="text" required>
  The parent domain, for example `example.com`.
</ParamField>
<ParamField body="nameserver" type="text" required>
  The child nameserver hostname to modify, for example `ns1.example.com`.
</ParamField>
<ParamField body="currentipaddress" type="text" required>
  The IP address currently assigned to the nameserver.
</ParamField>
<ParamField body="newipaddress" type="text" required>
  The new IP address to assign.
</ParamField>

### Request

<CodeGroup>
```bash cURL
curl -s "$ENDPOINT/domains/example.com/nameservers/modify" \
  -H "username: $EMAIL" \
  -H "token: $TOKEN" \
  --data "nameserver=ns1.example.com" \
  --data "currentipaddress=192.0.2.1" \
  --data "newipaddress=192.0.2.2"
```

```python Python
resp = requests.post(f"{ENDPOINT}/domains/example.com/nameservers/modify",
                     headers={"username": EMAIL, "token": token()},
                     data={
                         "nameserver": "ns1.example.com",
                         "currentipaddress": "192.0.2.1",
                         "newipaddress": "192.0.2.2",
                     })
print(resp.json())
```
</CodeGroup>

## Delete a child nameserver

Remove an existing child nameserver from the domain.

`POST /domains/{domain}/nameservers/delete`

### Parameters

<ParamField path="domain" type="text" required>
  The parent domain, for example `example.com`.
</ParamField>
<ParamField body="nameserver" type="text" required>
  The child nameserver hostname to delete, for example `ns1.example.com`.
</ParamField>

### Request

<CodeGroup>
```bash cURL
curl -s "$ENDPOINT/domains/example.com/nameservers/delete" \
  -H "username: $EMAIL" \
  -H "token: $TOKEN" \
  --data "nameserver=ns1.example.com"
```

```python Python
resp = requests.post(f"{ENDPOINT}/domains/example.com/nameservers/delete",
                     headers={"username": EMAIL, "token": token()},
                     data={"nameserver": "ns1.example.com"})
print(resp.json())
```
</CodeGroup>

<Note>
  Child nameserver registration, modification, and deletion depend on the registrar module backing your account. On registrars that do not support glue records, these calls return a `501` "Function not supported by the registrar module".
</Note>
