This is the full reference for the WireGuard REST API: every endpoint, the status and error codes, and the bandwidth and DNS-over-TLS endpoints. To get started with keys and authentication, see WireGuard REST API: Getting Started.
All endpoints
Base URL: https://portal.premiervpn.net/api/wg
| Method | Endpoint | Description |
|---|---|---|
| GET | /servers | List your servers |
| GET | /servers/{assignment_id}/users | List users with live status and data usage |
| POST | /servers/{assignment_id}/users | Create a user. Returns its config and keys. |
| GET | /servers/{assignment_id}/status | Live status for all your devices on the server |
| GET | /users/{user_id} | Get a user's details, config, keys and status |
| DELETE | /users/{user_id} | Remove a user and its port forwards |
| GET | /users/{user_id}/port-forwards | List a user's port forwards |
| POST | /users/{user_id}/port-forwards | Add a port forward |
| DELETE | /port-forwards/{port_forward_id} | Remove a port forward |
| GET | /users/{user_id}/bandwidth | Get a user's bandwidth limit |
| PUT | /users/{user_id}/bandwidth | Set a user's download and upload limit |
| DELETE | /users/{user_id}/bandwidth | Remove a user's limit |
| GET | /servers/{assignment_id}/dns | Get the server's DNS settings |
| PUT | /servers/{assignment_id}/dns | Set DNS-over-TLS resolvers |
| DELETE | /servers/{assignment_id}/dns | Turn off DNS-over-TLS and go back to plain DNS |
{assignment_id}: theassignment_idfromGET /servers(not the server'sid).{user_id}: the user'sidfrom the users list or the create response.{port_forward_id}: theidof a port forward.
Examples for users and status are in API: Managing Servers and Users. Port forwarding is in API: Port Forwarding.
Headers
Authorization: Bearer wg_your_api_key_here
Accept: application/json
Content-Type: application/json
Send Content-Type on POST and PUT requests with a JSON body. Always send Accept: application/json. Without it, validation errors may come back as a redirect instead of JSON.
Create keys in the portal under WireGuard › Manage Server › API Keys & Documentation. You can have up to 5 active keys, and each key works for all your servers. If you want separate keys for different apps or environments, such as production and testing, create one for each.
Rate limit
60 requests per minute per key. Over that, you get 429 with the code rate_limited.
Status codes
| Status | Meaning |
|---|---|
| 200 | Success |
| 201 | Created (user or port forward) |
| 401 | Missing or invalid API key |
| 403 | The server, user or port forward isn't on your account |
| 404 | No server, user or port forward with that ID |
| 409 | Conflict: the name or port is already in use on this server |
| 422 | Invalid input, or a reserved port |
| 429 | Rate limit exceeded |
| 500 | The action failed on the server. Check the error message. |
Error codes
Most errors return {"error": "...", "code": "..."}.
| Code | Status | Meaning |
|---|---|---|
missing_api_key | 401 | No Bearer token was sent |
invalid_api_key | 401 | The key is wrong or has been revoked |
rate_limited | 429 | More than 60 requests in a minute |
forbidden | 403 | The resource isn't on your account |
name_unavailable | 409 | That user name is already used on this server |
port_unavailable | 409 | That port and protocol are already forwarded on this server |
port_reserved | 422 | The external port is reserved |
creation_failed | 500 | A user or port forward couldn't be created |
deletion_failed | 500 | A user or port forward couldn't be removed |
status_failed | 500 | Device status couldn't be read from the server |
Validation errors (422) use a different shape: a message plus an errors object listing each problem field. Bandwidth and DNS endpoints return only an error message, without a code.
Bandwidth limits
Set a download and upload speed limit for one user. Limits apply straight away and are reapplied when the server restarts.
Set a limit
PUT /users/{user_id}/bandwidth
curl -s -X PUT \
-H "Authorization: Bearer wg_YOUR_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"down_mbps": 10, "up_mbps": 5}' \
https://portal.premiervpn.net/api/wg/users/42/bandwidth
| Field | Description |
|---|---|
down_mbps or down_kbps | Download limit (traffic to the device) |
up_mbps or up_kbps | Upload limit (traffic from the device) |
Send both a download and an upload value, in Mbps or Kbps. Each must be between 100 Kbps and 1,000,000 Kbps (1 Gbps). Anything outside that returns 422.
Response:
{
"success": true,
"client_name": "phone",
"bandwidth_down_kbps": 10000,
"bandwidth_up_kbps": 5000,
"bandwidth_down_mbps": 10.0,
"bandwidth_up_mbps": 5.0
}
Check a limit
GET /users/{user_id}/bandwidth
{
"user_id": 42,
"client_name": "phone",
"client_ip": "10.66.66.4",
"bandwidth_down_kbps": 10000,
"bandwidth_up_kbps": 5000,
"bandwidth_down_mbps": 10.0,
"bandwidth_up_mbps": 5.0,
"limited": true
}
A user with no limit has "limited": false and null values.
Remove a limit
DELETE /users/{user_id}/bandwidth
{
"success": true,
"message": "Bandwidth limit removed."
}
Remove a user's limit before you delete the user. Otherwise the limit can stay on the server and apply to the next user given the same internal IP.
DNS-over-TLS
These endpoints set up DNS-over-TLS (using Stubby) for your server's own DNS lookups. Stubby is installed on the server the first time you use them.
Your devices keep using the DNS servers in their config files (the DNS line). Changing these settings doesn't change the DNS your devices use. To change that, download a new config with the Custom Config Builder in the portal.
Set resolvers
PUT /servers/{assignment_id}/dns
curl -s -X PUT \
-H "Authorization: Bearer wg_YOUR_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"resolvers": [
{"address": "1.1.1.1", "name": "cloudflare-dns.com"},
{"address": "9.9.9.9", "name": "dns.quad9.net"}
]}' \
https://portal.premiervpn.net/api/wg/servers/5/dns
| Field | Description |
|---|---|
resolvers | Required. A list of 1 to 4 resolvers. |
resolvers[].address | Required. The resolver's IP address. |
resolvers[].name | The resolver's TLS hostname. Include it: the server checks this name before it trusts the resolver. |
resolvers[].port | Optional. Defaults to 853. |
Response:
{
"success": true,
"message": "DoT configured with 2 resolver(s).",
"resolvers": [
{"address": "1.1.1.1", "name": "cloudflare-dns.com"},
{"address": "9.9.9.9", "name": "dns.quad9.net"}
]
}
Check DNS settings
GET /servers/{assignment_id}/dns
With DNS-over-TLS on:
{
"mode": "dot",
"stubby_active": true,
"resolvers": [
{"address": "1.1.1.1", "port": 853, "name": "cloudflare-dns.com", "type": "dot"}
]
}
With it off, mode is plain and each resolver has "type": "plain".
Go back to plain DNS
DELETE /servers/{assignment_id}/dns
{
"success": true,
"message": "DoT removed. Reverted to plain DNS."
}
Common DNS-over-TLS resolvers
| Provider | Address | TLS name |
|---|---|---|
| Cloudflare | 1.1.1.1 | cloudflare-dns.com |
| Cloudflare (blocks malware) | 1.1.1.2 | security.cloudflare-dns.com |
| Quad9 (blocks malware) | 9.9.9.9 | dns.quad9.net |
| 8.8.8.8 | dns.google |
Example: full workflow
# 1. List servers to get the assignment_id
curl -s -H "Authorization: Bearer wg_YOUR_KEY" -H "Accept: application/json" \
https://portal.premiervpn.net/api/wg/servers
# 2. Create a user on assignment 5 (note the returned user id)
curl -s -X POST -H "Authorization: Bearer wg_YOUR_KEY" -H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"client_name": "web-server"}' \
https://portal.premiervpn.net/api/wg/servers/5/users
# 3. Get the user's config and save it as a .conf file
curl -s -H "Authorization: Bearer wg_YOUR_KEY" -H "Accept: application/json" \
https://portal.premiervpn.net/api/wg/users/USER_ID
# 4. Forward HTTPS to the new user
curl -s -X POST -H "Authorization: Bearer wg_YOUR_KEY" -H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"external_port": 443, "internal_port": 443, "protocol": "tcp"}' \
https://portal.premiervpn.net/api/wg/users/USER_ID/port-forwards
# 5. Check the device is online
curl -s -H "Authorization: Bearer wg_YOUR_KEY" -H "Accept: application/json" \
https://portal.premiervpn.net/api/wg/servers/5/status
# 6. Clean up: remove the port forward, then the user
curl -s -X DELETE -H "Authorization: Bearer wg_YOUR_KEY" -H "Accept: application/json" \
https://portal.premiervpn.net/api/wg/port-forwards/PORT_FORWARD_ID
curl -s -X DELETE -H "Authorization: Bearer wg_YOUR_KEY" -H "Accept: application/json" \
https://portal.premiervpn.net/api/wg/users/USER_ID