### Fetch one subscriber

`GET /api/v1/users/{id}`

The full record, including the computed status object and the fields the list projection leaves out.

- Authentication: manager session (JWT) or API token
- Permission: `prm_users_index` (View users)
- Risk: read

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | Subscriber id. |

#### Response — 200 OK

```json
{
  "data": {
    "id": 4711,
    "tenant_id": 12,
    "username": "ahmed",
    "enabled": true,
    "status": { "online": true, "expired": false, "have_quota": true, "can_connect": true },
    "profile_id": 7,
    "fup_profile_id": null,
    "bytes_remaining": 48318382080,
    "seconds_remaining": null,
    "expiration": "2026-10-14 00:00:00",
    "balance": 0.00,
    "debt": 0.00,
    "debt_limit": null,
    "mac_lock_enabled": false,
    "mac_locked_addrs": [],
    "simultaneous_sessions": 1,
    "allowed_services": "both",
    "lookup_token": "n8Qk2vRa1pLd7WxYzB0cEf",
    "custom_fields": {},
    "created_at": "2026-03-02 11:40:12"
  }
}
```

#### Errors

| Code | Status | When |
| --- | --- | --- |
| `ERR_NOT_FOUND` | 404 | no such subscriber, or one outside the caller's manager subtree |

#### Note

A subscriber that exists but sits outside your subtree returns the same 404 as one that does not exist, byte for byte including details.reason. That is deliberate: a 403 would confirm the id and make the id space enumerable.

