Querying Proxmox VMs via API: Troubleshooting and Success
Introduction
Proxmox offers a powerful API for managing virtual machines, but getting it to work correctly requires understanding its authentication model, permissions, and API structure. Recently, I went through the process of pulling a list of all running VMs using Proxmox’s API and ran into some pitfalls that might trip up others. This post walks through what I learned and what ultimately worked.
The Goal: Retrieve a List of All Proxmox VMs
The task was simple: use cURL to fetch a list of all virtual machines from a Proxmox cluster via its API. This information is useful for automation, monitoring, or integrating Proxmox data into other systems.
The Proxmox API endpoint we needed to query was:
https://<proxmox-host>:8006/api2/json/cluster/resources?type=vm
First Attempt: Hitting the API with a Token
Proxmox supports API authentication via PVEAPIToken, which is more secure than using a username and password in scripts. So I generated an API token for root@pam
and used the following cURL
command:
curl -k -s -X GET "https://<proxmox-host>:8006/api2/json/cluster/resources?type=vm" \
-H 'Authorization: PVEAPIToken=root@pam!mytokenid=mytokensecret'
But there was no output—not even an error message. This led me into troubleshooting mode.
Debugging the Issue
1. Checking Authentication
To see what was happening behind the scenes, I added -v
(verbose mode):
curl -k -s -X GET "https://<proxmox-host>:8006/api2/json/cluster/resources?type=vm" \
-H 'Authorization: PVEAPIToken=root@pam!mytokenid=mytokensecret' -v
This confirmed that the token was authenticating successfully, but the response contained empty data instead of the expected list of VMs.
2. Checking API Token Permissions
After reviewing the token settings in the Proxmox Web UI (Datacenter -> Permissions -> API Tokens
), I found that I had mistakenly left privilege separation enabled when generating the token. This setting restricted API calls and prevented certain queries from returning data.
Solution: I regenerated the token and made sure to uncheck privilege separation, which allowed the token to retrieve the necessary VM information.
3. Checking Node Names
By default, Proxmox expects API calls to be made against a specific node. Since we were using a cluster-wide endpoint (/cluster/resources
), this shouldn’t have been an issue. But when querying individual VM details, the correct node name is required.
To list available nodes:
curl -k -s -X GET "https://<proxmox-host>:8006/api2/json/nodes" \
-H 'Authorization: PVEAPIToken=root@pam!mytokenid=mytokensecret' | jq -r '.data[].node'
This returned:
mcp
So for node-specific API calls, I needed to replace <node>
with mcp
.
The Final Working cURL Command
Once the permissions were fixed, the following command successfully returned a list of VMs:
curl -k -s -X GET "https://<proxmox-host>:8006/api2/json/cluster/resources?type=vm" \
-H 'Authorization: PVEAPIToken=root@pam!mytokenid=mytokensecret' | jq -r '.data[] | "\(.vmid) - \(.name) - \(.node)"'
Example Output:
100 - WebServer - mcp
101 - Database - mcp
102 - Firewall - mcp
This command now works cluster-wide and provides VM IDs, names, and their associated node.
Key Takeaways
- API tokens require correct permissions – Uncheck privilege separation when generating them if you need full access.
- Use verbose mode (
-v
) for debugging – It helps identify authentication or network issues. - Ensure you’re querying the correct node – Some API endpoints require specifying the node name.
- Use
jq
to format output – It makes JSON data easier to read and process in scripts.
Now that I have VM listing working, the next step is pulling detailed network information, including MAC addresses, via the API. Stay tuned!