### Register a NAS

`POST /api/v1/admin/nas`

Creates the device record and its RADIUS shared secret. At least one of nas_identifier, nas_ip and called_station_id must be present — that is what an incoming RADIUS packet will be matched on.

- Authentication: manager session (JWT) or API token
- Permission: `prm_nas_create` (Add NAS)
- Risk: write
- Rate limit bucket: `t_mutate`

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `shared_secret` | body | string | yes | The RADIUS shared secret. Required. |
| `nas_identifier` | body | string | no | NAS-Identifier. Unique across the whole platform. |
| `nas_ip` | body | string | no | NAS-IP-Address. Unique across the whole platform. |
| `called_station_id` | body | string | no | Called-Station-Id. Unique across the whole platform. |
| `vendor` | body | string | no | Device vendor. Validated against the known-vendor catalogue. |
| `coa_port` | body | integer | no | RFC 5176 port. Omit for the schema default of 3799. |
| `ip_accounting_enabled` | body | boolean | no | Defaults to true when omitted. An explicit false is honoured. |

#### Request

```json
{
  "nas_identifier": "cairo-edge-2",
  "nas_ip": "10.20.0.2",
  "shared_secret": "a-long-random-secret",
  "description": "Nasr City edge 2",
  "vendor": "mikrotik",
  "coa_port": 3799
}
```

#### Errors

| Code | Status | When |
| --- | --- | --- |
| `ERR_VALIDATION` | 400 | shared_secret missing, no identity field supplied, or an unknown vendor |
| `ERR_CONFLICT` | 409 | the nas_ip, nas_identifier or called_station_id is already registered — possibly by another tenant |

#### Note

A 409 here can be caused by a device belonging to a tenant you cannot see. The three identity columns are globally unique because RADIUS resolves on the bare key before any tenant is known, so "already taken" does not mean "already in your list".

