Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/AZhur771/pivpn-web/llms.txt

Use this file to discover all available pages before exploring further.

These endpoints manage WireGuard peers by executing PiVPN CLI commands over an SSH connection to the host. Read operations parse /etc/wireguard/configs/clients.txt and the output of wg show all dump directly; write operations invoke pivpn add, pivpn remove, pivpn on, and pivpn off with the appropriate flags. Every endpoint requires a valid session cookie. Endpoints that modify state additionally require the logged-in user to have isAdmin: true — viewers receive 403 Forbidden.
All write operations — create, delete, enable, and disable — require the authenticated user to have isAdmin: true. If the user is authenticated but does not hold the admin role, the server responds with 403 Forbidden.
Client names are validated against the regex /[^a-z0-9 .,_-]/gim. Any character outside lowercase letters, uppercase letters, digits, spaces, ., ,, _, and - will cause the request to be rejected with a 500 error and the message "Invalid Client Name: <name>".

GET /api/wireguard/client

Returns a flat list of all registered WireGuard clients parsed from /etc/wireguard/configs/clients.txt on the PiVPN host. Each entry contains only the static identity fields; for live connection statistics use GET /api/wireguard/client-status. Requires: active session. Response200 OK, application/json
[
  {
    "name": "alice",
    "publicKey": "abc123...",
    "createdAt": "2024-01-15T10:30:00.000Z"
  }
]
[].name
string
The human-readable client name as supplied to pivpn add -n.
[].publicKey
string
The WireGuard public key for this peer, Base64-encoded.
[].createdAt
string (ISO 8601 date)
The Unix timestamp (in seconds) stored in clients.txt, converted to a JavaScript Date and serialised as an ISO 8601 string.
Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
curl example
curl -b cookies.txt http://localhost:3001/api/wireguard/client

GET /api/wireguard/client-status

Returns a list of ClientStatus objects that combine the static client records with live peer data from wg show all dump and the enabled/disabled state stored in /etc/wireguard/wg0.conf. Clients that appear in clients.txt but have not yet performed a handshake will have latestHandshake: null; clients not currently connected will have endpoint: null. Requires: active session. Response200 OK, application/json
[
  {
    "name": "alice",
    "publicKey": "abc123...",
    "createdAt": "2024-01-15T10:30:00.000Z",
    "iface": "wg0",
    "preSharedKey": "xyz789...",
    "enabled": true,
    "endpoint": "203.0.113.42:51820",
    "allowedIps": "10.6.0.2/32",
    "latestHandshake": "2024-01-15T11:45:00.000Z",
    "transferRx": 1048576,
    "transferTx": 524288,
    "persistentKeepalive": "25",
    "banned": false
  }
]
[].name
string
The human-readable client name.
[].publicKey
string
The WireGuard public key for this peer, Base64-encoded.
[].createdAt
string (ISO 8601 date)
The date this client was registered with PiVPN.
[].iface
string
The WireGuard interface this peer is associated with (e.g. wg0). May be absent if wg show all dump has not returned data for this peer yet.
[].preSharedKey
string
The pre-shared key for this peer as reported by wg show all dump. May be absent if not configured.
[].enabled
boolean
true when the peer block in wg0.conf is active. false when the block is prefixed with #[disabled], indicating the peer has been turned off via pivpn off.
[].endpoint
string | null
The host:port of the client’s most recent connection. null when the client is not currently connected (WireGuard reports (none)).
[].allowedIps
string
The allowed IP ranges for this peer as a comma-separated CIDR string (e.g. 10.6.0.2/32).
[].latestHandshake
string (ISO 8601 date) | null
The timestamp of the most recent successful handshake. null when the client has never connected (WireGuard reports 0).
[].transferRx
number
Total bytes received from this peer since the interface started, as reported by wg show all dump.
[].transferTx
number
Total bytes transmitted to this peer since the interface started, as reported by wg show all dump.
[].persistentKeepalive
string
The persistent keepalive interval in seconds as a string (e.g. "25"), or "off" if not configured.
[].banned
boolean
true when this client’s public key appears in the banned_client table. Banned clients are tracked in the PiVPN Web database.
Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
curl example
curl -b cookies.txt http://localhost:3001/api/wireguard/client-status

GET /api/wireguard/client/:name

Returns a single Client object for the peer whose name matches the :name path parameter. The lookup is performed against the full client list from clients.txt. Requires: active session. Path parameters
name
string
required
The exact name of the client to retrieve. Case-sensitive; must match the name stored in clients.txt.
Response200 OK, application/json
{
  "name": "alice",
  "publicKey": "abc123...",
  "createdAt": "2024-01-15T10:30:00.000Z"
}
name
string
The client name.
publicKey
string
The WireGuard public key, Base64-encoded.
createdAt
string (ISO 8601 date)
The date this client was registered.
Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
500{ "error": "Invalid Client: <name>" }No client with that name exists
curl example
curl -b cookies.txt http://localhost:3001/api/wireguard/client/alice

POST /api/wireguard/client/:name (Admin only)

Creates a new WireGuard peer by executing pivpn add -n <name> on the host over SSH. The name is validated before the SSH call is made — invalid characters produce an immediate 500 error without touching the host. After the pivpn add command completes the endpoint reads clients.txt again and returns the newly created Client object. Requires: active session with isAdmin: true. Path parameters
name
string
required
The desired client name. Must contain only letters (a–z, A–Z), digits (0–9), spaces, and the characters ., ,, _, -. Maximum length is not enforced by the API but is subject to PiVPN CLI limits.
Response200 OK, application/json
{
  "name": "alice",
  "publicKey": "abc123...",
  "createdAt": "2024-01-15T10:30:00.000Z"
}
Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
403{ "error": "Not enough rights" }Authenticated but not admin
500{ "error": "Invalid Client Name: <name>" }Name contains disallowed characters
500{ "error": "Duplicate Client: <name>" }A client with that name already exists
curl example
curl -b cookies.txt \
  -X POST http://localhost:3001/api/wireguard/client/alice

DELETE /api/wireguard/client/:name (Admin only)

Removes an existing WireGuard peer by executing pivpn remove --yes <name> on the host. The client record is fetched before deletion so that its data can be returned in the response. The --yes flag suppresses the interactive confirmation prompt. Requires: active session with isAdmin: true. Path parameters
name
string
required
The exact name of the client to delete.
Response200 OK, application/json — the deleted client’s data.
{
  "name": "alice",
  "publicKey": "abc123...",
  "createdAt": "2024-01-15T10:30:00.000Z"
}
Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
403{ "error": "Not enough rights" }Authenticated but not admin
500{ "error": "Invalid Client: <name>" }No client with that name exists
curl example
curl -b cookies.txt \
  -X DELETE http://localhost:3001/api/wireguard/client/alice

POST /api/wireguard/client/:name/enable (Admin only)

Re-enables a previously disabled peer by running pivpn on --yes <name> on the host. This restores the peer’s block in wg0.conf by removing the #[disabled] comment prefix. Requires: active session with isAdmin: true. Path parameters
name
string
required
The exact name of the client to enable.
Response200 OK, application/json — the client’s data.
{
  "name": "alice",
  "publicKey": "abc123...",
  "createdAt": "2024-01-15T10:30:00.000Z"
}
Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
403{ "error": "Not enough rights" }Authenticated but not admin
500{ "error": "Invalid Client: <name>" }No client with that name exists
curl example
curl -b cookies.txt \
  -X POST http://localhost:3001/api/wireguard/client/alice/enable

POST /api/wireguard/client/:name/disable (Admin only)

Disables a peer without removing it by running pivpn off --yes <name> on the host. PiVPN comments out the peer block in wg0.conf with a #[disabled] prefix, preventing the interface from accepting connections from this peer. Requires: active session with isAdmin: true. Path parameters
name
string
required
The exact name of the client to disable.
Response200 OK, application/json — the client’s data.
{
  "name": "alice",
  "publicKey": "abc123...",
  "createdAt": "2024-01-15T10:30:00.000Z"
}
Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
403{ "error": "Not enough rights" }Authenticated but not admin
500{ "error": "Invalid Client: <name>" }No client with that name exists
curl example
curl -b cookies.txt \
  -X POST http://localhost:3001/api/wireguard/client/alice/disable

GET /api/wireguard/client/:name/qrcode.svg

Generates a QR code from the client’s WireGuard .conf file and returns it as an inline SVG image. The QR code encodes the full WireGuard configuration, making it straightforward to import a VPN profile on a mobile device by scanning it with the WireGuard app. The SVG is rendered at 512 × 512 pixels using the qrcode library. The response is sent with Content-Type: image/svg+xml. Requires: active session. Path parameters
name
string
required
The exact name of the client whose QR code to generate.
Response200 OK, image/svg+xml — raw SVG markup. Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
500{ "error": "Invalid Client: <name>" }No client with that name exists
curl example — display inline or save to file
# Save to file
curl -b cookies.txt \
  http://localhost:3001/api/wireguard/client/alice/qrcode.svg \
  -o alice-qrcode.svg

# Open directly in a browser (macOS)
open http://localhost:3001/api/wireguard/client/alice/qrcode.svg

GET /api/wireguard/client/:name/configuration

Returns the raw WireGuard configuration file for the client, read from /etc/wireguard/configs/<name>.conf on the PiVPN host. The response triggers a file download via the Content-Disposition: attachment header. Requires: active session. Path parameters
name
string
required
The exact name of the client whose configuration file to download.
Response200 OK, text/plain
HeaderValue
Content-Typetext/plain
Content-Dispositionattachment; filename="<name>.conf"
The body is the plain-text WireGuard INI-format configuration file, for example:
[Interface]
PrivateKey = <client-private-key>
Address = 10.6.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = <server-public-key>
PresharedKey = <preshared-key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
Error responses
StatusBodyWhen
401{ "error": "Invalid Session: <id>" }No valid session
500{ "error": "Invalid Client: <name>" }No client with that name exists
curl example
curl -b cookies.txt \
  http://localhost:3001/api/wireguard/client/alice/configuration \
  -o alice.conf

Build docs developers (and LLMs) love