Advanced

Proxmox API Authentication: Tickets vs API Tokens with Examples

Master Proxmox VE API authentication using both ticket-based sessions and API tokens. Includes curl examples, common 401/403 errors, CSRF token handling, and best practices for automation.

ProxmoxR app icon

Managing Proxmox? Try ProxmoxR

Monitor and control your VMs & containers from your phone.

Try Free

Two Authentication Methods

The Proxmox VE REST API supports two authentication mechanisms: ticket-based authentication (session cookies) and API token authentication (persistent tokens). Both provide access to the same API endpoints, but they differ in how credentials are obtained, how long they last, and how they handle CSRF protection. Choosing the right method depends on whether you are building interactive tools or headless automation.

Method 1: Ticket-Based Authentication

Ticket authentication works like a web login. You POST credentials to the /access/ticket endpoint and receive a session cookie (PVEAuthCookie) and a CSRF prevention token. The ticket expires after 2 hours.

# Step 1: Obtain a ticket
curl -k -s -d "username=root@pam&password=YOUR_PASSWORD" \
    https://192.168.1.100:8006/api2/json/access/ticket | jq .

# Response:
# {
#   "data": {
#     "ticket": "PVE:root@pam:66A1B2C3::BASE64_DATA...",
#     "CSRFPreventionToken": "66A1B2C3:BASE64_DATA...",
#     "username": "root@pam"
#   }
# }

# Step 2: Store the ticket and CSRF token
TICKET=$(curl -k -s -d "username=root@pam&password=YOUR_PASSWORD" \
    https://192.168.1.100:8006/api2/json/access/ticket | \
    jq -r '.data.ticket')

CSRF=$(curl -k -s -d "username=root@pam&password=YOUR_PASSWORD" \
    https://192.168.1.100:8006/api2/json/access/ticket | \
    jq -r '.data.CSRFPreventionToken')

# Better: capture both in one request
RESPONSE=$(curl -k -s -d "username=root@pam&password=YOUR_PASSWORD" \
    https://192.168.1.100:8006/api2/json/access/ticket)
TICKET=$(echo "$RESPONSE" | jq -r '.data.ticket')
CSRF=$(echo "$RESPONSE" | jq -r '.data.CSRFPreventionToken')

# Step 3: Use the ticket for GET requests (no CSRF needed)
curl -k -b "PVEAuthCookie=$TICKET" \
    https://192.168.1.100:8006/api2/json/cluster/status | jq .

# Step 4: Use ticket + CSRF for POST/PUT/DELETE requests
curl -k -b "PVEAuthCookie=$TICKET" \
    -H "CSRFPreventionToken: $CSRF" \
    -X POST \
    https://192.168.1.100:8006/api2/json/nodes/pve/qemu/100/status/start

Ticket authentication is what the Proxmox web UI uses internally. It is suitable for short-lived scripts and interactive applications, but the 2-hour expiry and CSRF requirement make it cumbersome for long-running automation.

Method 2: API Token Authentication

API tokens are persistent credentials tied to a user account. They do not expire (unless you set an expiry), do not require CSRF tokens, and can optionally have their permissions separated from the parent user. This makes them ideal for automation, monitoring, and third-party integrations.

# Create an API token via the CLI
pveum user token add root@pam automation --privsep 0
# Output:
# ┌──────────────┬──────────────────────────────────────────────┐
# │ key          │ value                                        │
# ╞══════════════╪══════════════════════════════════════════════╡
# │ full-tokenid │ root@pam!automation                          │
# │ info         │ {"privsep":"0"}                              │
# │ value        │ aabbccdd-1122-3344-5566-778899aabbcc         │
# └──────────────┴──────────────────────────────────────────────┘
# IMPORTANT: Save the token value now - it cannot be retrieved later

# Use the API token for any request (GET, POST, PUT, DELETE)
# No CSRF token needed!
curl -k -H "Authorization: PVEAPIToken=root@pam!automation=aabbccdd-1122-3344-5566-778899aabbcc" \
    https://192.168.1.100:8006/api2/json/cluster/status | jq .

# POST request with API token - no CSRF required
curl -k -H "Authorization: PVEAPIToken=root@pam!automation=aabbccdd-1122-3344-5566-778899aabbcc" \
    -X POST \
    https://192.168.1.100:8006/api2/json/nodes/pve/qemu/100/status/start

Privilege Separation

When creating an API token, the --privsep flag controls whether the token inherits the parent user's full permissions:

# privsep=0: Token has the SAME permissions as the parent user
pveum user token add admin@pve full-access --privsep 0

# privsep=1 (default): Token needs its OWN ACL entries
pveum user token add admin@pve limited-access --privsep 1

# Grant specific permissions to a privilege-separated token
pveum aclmod / -token 'admin@pve!limited-access' -role PVEVMUser

# List available roles
pveum role list

# Common roles for API tokens:
# PVEVMAdmin     - full VM management
# PVEVMUser      - basic VM operations (start, stop, console)
# PVEAuditor     - read-only access to everything
# PVEDatastoreUser - backup and restore operations

Common Authentication Errors

Here are the most frequent API authentication errors and their causes:

# 401 Unauthorized
# - Wrong password or token value
# - Expired ticket (older than 2 hours)
# - Token does not exist or was deleted
# - Using HTTP instead of HTTPS

# 403 Forbidden
# - User/token lacks required permissions
# - Missing CSRF token on a POST/PUT/DELETE with ticket auth
# - privsep=1 token without explicit ACL entries

# Debug: check authentication with verbose curl
curl -k -v -H "Authorization: PVEAPIToken=root@pam!automation=your-token" \
    https://192.168.1.100:8006/api2/json/version 2>&1 | grep -E '< HTTP|< Content'

# Verify token exists and its permissions
pveum user token list root@pam
pveum acl list

Ticket vs Token Comparison

  • Lifespan: Tickets expire in 2 hours. Tokens persist until deleted (or optional expiry date).
  • CSRF protection: Tickets require a CSRFPreventionToken header on mutating requests. Tokens do not.
  • Creation: Tickets are created with username/password. Tokens are created once and reused.
  • Security: Tickets do not expose the user's password after initial auth. Tokens are long-lived secrets that must be stored securely.
  • Use case: Tickets for interactive/short-lived sessions. Tokens for automation, CI/CD, monitoring tools.

Best Practices

For production automation, always prefer API tokens over ticket-based auth. Create a dedicated user with minimal permissions, generate a privilege-separated token, and grant only the ACLs needed for your specific use case. Store the token secret in a vault or secrets manager, never in source code.

ProxmoxR uses API token authentication to connect to your Proxmox nodes, which means no passwords are stored or transmitted after initial setup and no CSRF token juggling is needed. You can create a read-only token for monitoring or a full-access token for management, depending on how you want to use the app.

Take Proxmox management mobile

All the features discussed in this guide — accessible from your phone with ProxmoxR. Real-time monitoring, power control, firewall management, and more.

ProxmoxR

Manage Proxmox from your phone

Monitor, control, and manage your clusters on the go.

Free 7-day trial · No credit card required