How to solve "API Disabled" error?
Hello everyone,
I need to get a list of all devices currently available in KACE through the API. I have been reading the docs and following the instructions given there.
Although I have not been able to successfully get a list of all devices present in KACE. I am using the machines API to achieve this (please correct me if this is not the correct one).
If I don't provide the "x-dell-api-version" in the header of the request, the authentication is done correctly, I am to get the CSRF token in the header, but when I query the list of machines I get "API Disabled" error.
If I provide the "x-dell-api-version" in the header of the request, again the authentication is done correctly, I am to get the CSRF token in the header, but when I query the list of machines I get 'Invalid CSRF Token' error. I tried changing the version from 1 through 10 and get the same error for all of them.
KACE version: 11.1.263
My preferred language is Python3.9 and here is my code so far:
import requests url = "https://K1000/ams/shared/api/security/login" params = { "userName" : "{username}", "password" : "{password}" } headers = { "Content-Type": "application/json", "Accept": "application/json", # "x-dell-api-version": "5" } resp = requests.post(url, headers=headers, json=params, verify=False) url_machines = "https://K1000/api/inventory/machines" headers["x-dell-csrf-token"] = resp.headers["x-dell-csrf-token"] headers["cookie"] = resp.headers["Set-Cookie"].split(";")[0] resp2 = requests.get(url_machines, headers=headers, verify=False)
I tried following the solution here and here, but that didn't work for me.
Any help is appreciated.
Answers (2)
Your login headers have a commented-out entry for the following, and you must set this header.
Have you used Postman?
Does this Python example with your credentials and host work?
url = "https://k1000/ams/shared/api/security/login"
payload = json.dumps({ "userName": "admin",
"password": "password", "organizationName": "Default" })headers = { 'Accept': 'application/json',
'Content-Type': 'application/json', import json0import json1response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
Comments:
-
Hello Kevin, thank you for helping out. I am aware that "x-dell-API-version": "5" is commented out in the code, because if I pass it with the header I get: "Invalid CSRF token" error. I tried using version 1 through 10 but get the same error every time.
Also, I ran your code and it gives me the same result that I get with my code.
Maybe I didn't explain my issue properly, I am able to successfully get the CSRF token, it is the subsequent API calls that don't work.
If "x-dell-API-version": "5" is commented during authentication and subsequent API calls, I get "API Disabled" error
If "x-dell-API-version": "5" is not commented, I get "Invalid CSRF token" error.
In both the cases, I am able to get the CSRF token in the header of the first response.
I apologize for making it so complicated, but that is my issue. - mbhamral 3 years ago-
The code example in my previous post is fully functional. That example with the URL and credentials changed for your environment would have allowed you to authenticate. - KevinG 3 years ago
Top Answer
As noted in the API reference guide, there are required headers that need to be set, like the "x-dell-API-version" header.
https://support.quest.com/download/downloads?id=6113961
Depending on the choice of programming language, you may need to add additional code or use libraries to manage the cookies.
The following example using Python is fully functional code that will authenticate and list the devices in the JSON output. This example was tested in my Python 3.9 environment.
There are some print statements to show some of the expected output. They can be commented out.
import requests
import JSON
from requests.sessions import Session
session = Session();
# Start of POST to authenticate to SMA server.
# The x-dell-csrf-token is saved to be used in subsequent API calls.
# Change the URL IP and credentials for your environment.
url = "http://192.168.1.97/ams/shared/api/security/login"
payload = json.dumps({ "userName": "admin",
"password": "password",
"organizationName": "Default"
})
headers = { 'Accept': 'application/json',
'Content-Type': 'application/json',
'x-dell-api-version': '5'
}
response = session.post(url, headers=headers, data=payload)
# The following line will display the JSON returned from the response.
print(json.dumps(response.json(), indent = 3))
csrf_token = response.headers.get('x-dell-csrf-token')
# You should see the x-dell-csrf-token in the print output
print(csrf_token)
# The following API call will retrieve the list of devices on the SMA
url = "http://192.168.1.97/api/inventory/machines"
headers = { 'Accept': 'application/json',
'Content-Type': 'application/json',
'x-dell-api-version': '5',
'x-dell-csrf-token': csrf_token
}
response = session.get(url, headers=headers)
print(json.dumps(response.json(), indent = 3))
session.close()
Comments:
-
Hello Kevin, thank you for helping out again, this code works, I am able to get a list of devices. The only thing I had to change was use "https" and not "http" in both the urls. I am going to compare your code to mine and see what I did wrong.
Thank you once again. - mbhamral 3 years ago-
Glad to hear it worked for you. I believe the key here is using a session object to save the cookies between API calls. - KevinG 3 years ago