Docs / REST API / Users

Users API

Manage RADIUS users — the radcheck / radusergroup records behind authentication. All paths are under /api/v1.

Method Path Scope
GET /users users.read
GET /users/{username} users.read
POST /users users.write
PUT /users/{username} users.write
DELETE /users/{username} users.write
GET /users/{username}/sessions sessions.read

The user object

{
  "username": "alice",
  "enabled": true,
  "groups": ["premium", "wifi"],
  "expiration": "31 Dec 2026 23:59:59",
  "simultaneous_use": 2
}
  • enabledfalse means an Auth-Type := Reject check attribute is present (the user exists but can't authenticate).
  • groups — group names in priority order.
  • expiration — a FreeRADIUS date string, or null if the account never expires.
  • simultaneous_use — max concurrent sessions, or null for unlimited.

List users

GET /userspaginated (page, size, search).

curl -H "X-API-Key: $KEY" "https://your-host/api/v1/users?search=al&size=20"
{
  "total": 3,
  "page": 1,
  "size": 20,
  "items": [
    { "username": "alice", "enabled": true, "groups": ["premium"], "expiration": null, "simultaneous_use": 1 }
  ]
}

Get one user

GET /users/{username} → the user object, or 404 if there's no such user.

Create a user

POST /users201 with the created user.

Field Required Default Notes
username 1–64 chars
password The secret
password_type Cleartext-Password See below
enabled true false adds the reject attribute
groups [] Group names, applied in order
expiration null FreeRADIUS date string
simultaneous_use null Max concurrent sessions

Valid password_type values: Cleartext-Password, MD5-Password, NT-Password, SHA-Password, Crypt-Password.

curl -X POST -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
     -d '{"username":"alice","password":"s3cret","groups":["premium"],"simultaneous_use":2}' \
     https://your-host/api/v1/users

Returns 400 for an unknown password_type, 409 if the username already exists.

Update a user

PUT /users/{username} → the updated user. Every field is optional — omit a field to leave it untouched. This is a targeted update, not a full replace:

Field null / omitted Other values
password unchanged sets a new password (with password_type)
enabled unchanged true clears the reject attr, false adds it
expiration unchanged "" clears it, a date string sets it
simultaneous_use unchanged 0 clears the limit, >0 sets it
groups unchanged a list replaces all current memberships
# Disable a user and cap them to one session, leaving everything else alone
curl -X PUT -H "X-API-Key: $KEY" -H "Content-Type: application/json" \
     -d '{"enabled":false,"simultaneous_use":1}' \
     https://your-host/api/v1/users/alice

404 if the user doesn't exist, 400 for an invalid password_type.

Delete a user

DELETE /users/{username}204. Removes the user's check, reply, and group-membership rows. 404 if there's no such user.

A user's sessions

GET /users/{username}/sessionsscope sessions.read. Returns the user's accounting history (most recent first, up to 200), not a page envelope:

{
  "sessions": [
    { "acctsessionid": "…", "acctstarttime": "2026-07-20T10:00:00Z", "framedipaddress": "10.0.0.5", "…": "…" }
  ],
  "count": 12
}