# Reverse DNS

Request a reverse DNS (PTR) name for one of your server's IP addresses, and see the requests that are still open. Requesting needs `manage`; reading needs `read`.

## Request a reverse DNS name

`POST /servers/{id}/rdns` asks for `ip` to resolve to `hostname`. Needs an `Idempotency-Key`. The change is not made during your request: it is queued and applied shortly after, the same way as a request made in the client area.

| Body field | Rule |
|---|---|
| `ip` | An IPv4 or IPv6 address that belongs to this server (as listed in `ips` on [the server](servers.md)). |
| `hostname` | A full host name, such as `mail.example.com`: 4 to 253 characters, letters, digits and dashes in dot-separated labels, ending in a letter label. It is lower-cased and a trailing dot is dropped. |

```bash
curl -sS -X POST https://api.redswitches.com/v1/servers/srv_123/rdns \
  -H "Authorization: Bearer $REDSWITCHES_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"ip":"203.0.113.10","hostname":"mail.example.com"}'
```

```ts
const req = await rs.rdns.set("srv_123", { ip: "203.0.113.10", hostname: "mail.example.com" });
```

```python
req = client.rdns.set("srv_123", ip="203.0.113.10", hostname="mail.example.com")
```

```go
req, err := client.RDNS.Set(ctx, "srv_123", &redswitches.RDNSRequest{IP: "203.0.113.10", Hostname: "mail.example.com"})
```

```json
{
  "server_id": "srv_123",
  "ip": "203.0.113.10",
  "hostname": "mail.example.com",
  "state": "pending",
  "already_requested": false
}
```

The answer is `202 Accepted`. `already_requested` is true when the same name was already waiting for that IP; nothing new is queued then.

Rules:

- One open request per IP address.
- At most 20 requests per server per day. Over that: `429 action_limit` with `details.limit` and `details.per: "server_day"`.
- The server must be active: otherwise `409 server_not_active`.
- The IP must be on the server: otherwise `422 ip_not_on_server`.
- `hostname` `""` clears the PTR record.

### Changes carried out as actions

On some servers the change is carried out as an [action](actions.md), and clearing a name (`hostname` `""`) always is. The answer is then a `202` with an action id to follow with `GET /actions/{id}`:

```json
{
  "id": "act_42",
  "server_id": "srv_123",
  "ip": "203.0.113.10",
  "hostname": "mail.example.com",
  "state": "queued",
  "already_requested": false,
  "poll_after": 10
}
```

For those changes: the same IP with another hostname while a change is still open answers `409 server_busy`; the same hostname again returns the open action with `already_requested: true`. Other servers keep the `pending` answer above. Use the `id` field to tell the two answers apart: only the action answer has one.

## List open requests

`GET /servers/{id}/rdns` returns this server's requests made by your account that are pending or applied.

```bash
curl -sS https://api.redswitches.com/v1/servers/srv_123/rdns \
  -H "Authorization: Bearer $REDSWITCHES_API_KEY"
```

```ts
const { data } = await rs.rdns.list("srv_123");
```

```python
requests = client.rdns.list("srv_123").data
```

```go
list, err := client.RDNS.List(ctx, "srv_123")
```

```json
{
  "server_id": "srv_123",
  "data": [
    {
      "ip": "203.0.113.10",
      "hostname": "mail.example.com",
      "state": "pending",
      "requested": "2026-11-15T09:30:00Z",
      "action_id": null
    }
  ]
}
```

| Field | Meaning |
|---|---|
| `ip` | The address. |
| `hostname` | The requested name. |
| `state` | `pending` (waiting to be applied) or `applied`. |
| `requested` | When it was requested (UTC). |
| `action_id` | The action carrying the change out (such as `"act_42"`), or null for a request applied by the scheduled job. |

Changes carried out as actions appear too (the newest 20); their `state` is that action's state: `queued`, `running`, `done`, `failed` or `unknown`. The list holds the job's requests first (oldest first), then the action changes (newest first): to find the newest entry for an IP, sort by `requested`.
