Examples of Lucidum API v2
This chapter includes examples of the Lucidum API v2.
For details on the syntax for the Lucidum API v2, see the chapter on Endpoints.
Query Metadata
In this example, we query the list of fields for assets from the Lucidum database. The response includes the same list of fields for an asset that you see in the New Query page or Edit Query page when you click on the Field field (Explore button > Query Builder page> New Query/Edit Query page > Field field).
The response includes a description of each field and its data type.
cURL
curl --location 'https://test-host.company.com/CMDB/v2/data/metadata/asset' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer quoVnYQeDNicAOywkOKq'
Line 1. The cURL call. The method defaults to GET. The URL is host name plus the endpoint for this API.
Line 2. The header specifies to return results in JSON.
Line 3. The header specifies to use a Bearer Token for authentication and provides the bearer token.
Include the lines that start with “--header” in each call to the Lucidum API v2.
Python
import requests
url = "https://test-host.company.com/CMDB/v2/data/metadata/user"
headers = {'Authorization': 'Bearer quoVnYQeDNicAOywkOKq'}
response = requests.request("GET", url, headers=headers, verify=False)
print(response. Text)
Line 2. The method defaults to GET. The URL is host name plus the endpoint for this API.
Line 3. The header specifies to use a Bearer Token for authentication and provides the bearer token.
Response
The response includes over 3000 lines, so this is a sample of the response:
{
"metadata": [
{
"fieldName": "Asset with SSH",
"fieldDescription": "Asset with SSH added by custom field manager",
"dataType": "String",
"displayName": "Asset with SSH",
"fieldGroup": "Dynamic Fields"
},
{
"fieldName": "File_Bucket",
"fieldDescription": "File bucket name",
"dataType": "List",
"displayName": "Cloud Bucket",
"fieldGroup": "Data"
},
{
"fieldName": "Customer",
"fieldDescription": null,
"dataType": "String",
"displayName": "Customer",
"fieldGroup": "Extra Fields"
},
{
"fieldname": "Metric_Space",
"fieldDescription": "Cloudwatch metric space",
"dataType": "String",
"displayName": "Cloud Watch Metric Space",
"fieldGroup": "Compliance"
},
]
}
For each field, the response includes:
fieldname. Name to use with the Lucidum API v2.
fieldDescription. A description of the field.
datatype. The data type for the field.
displayName. How the field name appears in the Lucidum interface.
fieldGroup. The group where the field appears in the Lucidum interface.
Simple Query
This example is a simple query to the Lucidum Database, using the endpoint /CMDB/v2/data/cmdb.
This endpoint sends queries to the Lucidum database, using fields, operators, AND statements, and OR statements, as you would in the Query Builder in the Lucidum UI.
This API uses the POST method. If you are using cURL, specify “-X POST”
Simple Query: Request Body JSON
{
"table":"asset",
"query":[
[
{
"searchFieldName":"Data_Classification",
"operator":"==",
"type":"String",
"value":"Restricted"
}
]
]
}
"paging": {
"page": 0,
"recordsPerPage": 20
}
}
Line 2. Define the table parameter. In this example, we will query the “asset” table
Line 3. Define the query parameter. Line
Line 6. the record must include the field name “Data_Classification”
Line 7. the “Data_Classification” field contains an exact match
Line 9. to the value “Restricted”
Line 8. Data_Classification has a data type of String
Line 14-17. Specify pagination
Simple Query: Response
The response includes the entire asset record for each asset where Data_Classification is “Restricted”.
Each asset includes over 300 lines in the response. Here is an abbreviated response:
{
"totalRecords": 465,
"data": [
{
"_id": "6461f100081577f5c85d7bc6",
"_time": 1684139969,
"run_time": 1684139969,
"Asset_Name": "I-087EBEBD8628B8A23",
"Is_Public": null,
"Last_Discovered_Datetime": 1684139334,
"Source_User_Name": [
"api.user",
"charles",
],
"Services": [
"https"
],
"FQDN": [
"ip-172-21-50-93.ec2.internal"
],
"MAC_Address": [
"16:81:1b:83:f3:b5"
],
"IP_Address": [
"172.21.50.93"
],
"Open_Port_List": [
"443"
],
"Host_Name": [
"I-087EBEBD8628B8A23"
],
},
{
"_id": "6461f100081577f5c85d7bcf",
"_time": 1684139969,
"run_time": 1684139969,
"Asset_Name": "I-0CE13EE75724B2BE7",
"Is_Public": 1.0,
"Last_Discovered_Datetime": 1684138734,
"Source_User_Name": [
"KY"
],
"Services": [
"https",
],
"FQDN": [
"ip-172-16-50-31.us-west-1.compute.internal"
],
"MAC_Address": [
"06:93:56:6d:85:99"
],
"IP_Address": [
"172.16.50.31",
"52.52.161.135"
],
"Open_Port_List": [
"443",
],
"Host_Name": [
"I-0CE13EE75724B2BE7"
],
}
],
"totalPages": 24,
"recordsPerPage": 20,
"page": 0
}
Query with AND
AND means that the results must meet all the criteria in a multi-part query.
In this example, our multi-part query includes two criteria. To specify AND, we enclose the first part of the AND query with “[“ and “],” (open square bracket and close square bracket followed by a trailing comma). We enclose the second part of the AND query with “[“ and “]” (open square bracket and close square bracket with no trailing comma).
Note that you can include as many AND statements in a query as you require; you are not limited to two criteria.
Query with AND: Request Body JSON
{
"table":"asset",
"query":[
[
{
"searchFieldName":"Is_Cloud_Device",
"operator":"==",
"type":"Binary",
"value":"Yes"
}
],
[
{
"searchFieldName":"OS",
"operator":"==",
"type":"String",
"value":"Windows Server 2019"
}
]
],
"paging": {
"page": 0,
"recordsPerPage": 5
}
}
Line 2. Define the table parameter. In this example, we will query the “asset” table
Line 3. Define the query parameter.
Line 6. the record must include the field name “Is_Cloud_Device”
Line 7. the “Is_Cloud_Device” field contains an exact match
Line 9. to the value “Yes”
Line 8. Is_Cloud_Device has a data type of String
Line 11. AND
Line 14. the record must include the field name “OS”
Line 15. the “OS” field contains an exact match
Line 17. to the value “Windows Server 2019”
Line 16. OS has a data type of String
Lines 21-24. Specify pagination
Query with AND: Response
The response includes the entire asset record for each asset that matches both Is_Cloud_Device is “Yes” and OS is “Windows Server 2019”.
The response is over 2700 lines. Here is an abbreviated response:
{
"totalRecords": 230,
"data": [
{
"_id": "6461f102081577f5c85d8371",
"_time": 1684139969,
"run_time": 1684139969,
"Asset_Name": "I-ZOW1CU6BPI4VFX2WZ",
"Is_Public": null,
"Last_Discovered_Datetime": 1684133227,
"Services": [
"http"
],
"FQDN": [
"ip-172-30-90-37.us-west-1.compute.internal"
],
"app": [
{
"Name": "Jenkins",
"Version": "Jenkins (ver 2.240)",
"Source": [
"orca_asset",
"tenable_scan"
],
"MAC_Address": [
"a0:6a:44:9a:b5:c1"
],
"IP_Address": [
"172.30.90.37",
"174.226.65.117"
],
"Open_Port_List": [
"27017",
"3389"
],
"Host_Name": [
"I-ZOW1CU6BPI4VFX2WZ"
]
},
{
"_id": "6461f102081577f5c85d835f",
"_time": 1684139969,
"run_time": 1684139969,
"Asset_Name": "I-ZDKH976IZQRFC2IPZ",
"Is_Public": null,
"Last_Discovered_Datetime": 1684133227,
"Services": [
"https",
"ssh"
],
"FQDN": [
"ip-10-31-97-175.us-west-1.compute.internal"
],
"app": [
{
"Name": "Jenkins",
"Version": "Jenkins (ver 2.240)",
"Source": [
"orca_asset",
"tenable_scan"
]
],
"MAC_Address": [
"b8:da:f1:27:db:2f"
],
"IP_Address": [
"10.31.97.175"
],
"Open_Port_List": [
"443"
],
"Host_Name": [
"I-ZDKH976IZQRFC2IPZ"
]
}
],
"totalPages": 46,
"recordsPerPage": 5,
"page": 0
}
Query with OR
OR means that the results must meet one of the criteria in a multi-part query.
In this example, our multi-part query includes two criteria. To specify OR, we enclose the first part of the OR query with “{“ and “},” (open curly bracket and close curly bracket followed by a trailing comma). We enclose the second part of the OR query with “{“ and “}” (open curly bracket and close curly bracket with no trailing comma).
Note that you can include as many OR statements in a query as you require; you are not limited to two criteria.
Query with OR: Request Body JSON
{
"table": "asset",
"query": [
[
{
"searchFieldName": "sourcetype",
"operator": "match",
"type": "List",
"value": "gcp_inventory"
},
{
"searchFieldName": "sourcetype",
"operator": "match",
"type": "List",
"value": "aws_ec2"
}
]
]
}
"paging": {
"page": 0,
"recordsPerPage": 20
}
}
In this example:
Note that the body uses JSON syntax. For information on JSON syntax, see https://www.w3schools.com/js/js_json_syntax.asp
Line 2. Define the table parameter. We will query the “asset” table in the Lucidum database
Line 3. Define the query parameter
Line 6. The query should search for records that include the field name “sourcetype”
Line 7. the “sourcetype” field must match
Line 9. to the value “gcp_inventory”
Line 8. sourcetype has a data type of List
Line 10. OR
Line 12. the query should search for records that includes the field name “sourcetype”
Line 13. the “sourcetype” field must match
Line 15. to the value “aws_ec2”
Line 14. sourcetype has a data type of List
Query with OR: Response
The response includes records where the data source (sourcetype) is “gcp_inventory” (GCP Virtual Machines) and records where the data source (sourcetype) is “aws_ec2” (Amazon Elastic Compute Cloud).
The response has over 9,000 lines. Here is an abbreviated response:
{
"totalRecords": 15,
"data": [
{
"_id": "6461f100081577f5c85d7bd1",
"_time": 1684139969,
"run_time": 1684139969,
"Asset_Name": "I-0DD75209275E7765B",
"Is_Public": 1.0,
"Last_Discovered_Datetime": 1684138758
"Services": [
"ssh",
"ms-wbt-server"
],
"FQDN": [
"ec2-52-40-174-46.us-west-2.compute.amazonaws.com",
"ip-10-0-1-205.us-west-2.compute.internal"
],
"MAC_Address": [
"0a:0c:dc:ee:9a:5b"
],
"IP_Address": [
"10.0.1.205",
"52.40.174.46"
]
},
{
"_id": "6461f100081577f5c85d7bc3",
"_time": 1684139969,
"run_time": 1684139969,
"Asset_Name": "I-07FD1B287AB682E99",
"Is_Public": null,
"Last_Discovered_Datetime": 1684138758,
"Services": [
"ms-wbt-server"
],
"FQDN": [
"ec2-54-203-115-170.us-west-2.compute.amazonaws.com",
"ip-172-31-6-11.us-west-2.compute.internal"
],
"MAC_Address": [
"0a:4e:a3:ce:c8:f9"
],
"IP_Address": [
"172.31.6.11",
"54.203.115.170"
],
}
],
"totalPages": 1,
"recordsPerPage": 20,
"page": 0
}
Query with OR and AND
OR means that the results must meet one of the criteria in a multi-part query.
AND means that the results must meet all the criteria in a multi-part query.
In this example, our multi-part query includes two criteria for AND. One of the AND criteria includes an OR.
To specify AND, we enclose the first part of the AND query with “[“ and “],” (open square bracket and close square bracket followed by a trailing comma). We enclose the second part of the AND query with “[“ and “]” (open square bracket and close square bracket with no trailing comma).
To specify OR, we enclose the first part of the OR query with “{“ and “},” (open curly bracket and close curly bracket followed by a trailing comma). We enclose the second part of the OR query with “{“ and “}” (open curly bracket and close curly bracket with no trailing comma).
Query with OR and AND: Request Body JSON
{
"table":"asset",
"query":[
[
{
"searchFieldName":"OS",
"operator":"==",
"type":"String",
"value":"Windows Server 2020"
},
{
"searchFieldName":"OS",
"operator":"==",
"type":"String",
"value":"Windows Server 2019"
}
],
[
{
"searchFieldName":"sourcetype",
"operator":"not match",
"type":"List",
"value":"sentinel"
}
]
],
"paging": {
"page": 0,
"recordsPerPage": 5
}
}
In this example:
Note that the body uses JSON syntax. For information on JSON syntax, see https://www.w3schools.com/js/js_json_syntax.asp
Line 2. Define the table parameter. We will query the “asset” table in the Lucidum database
Line 3. Define the query parameter
Line 6. The query should search for records that include the field name “OS”
Line 7. the “OS” field must exactly match
Line 9. to the value “Windows Server 2020”
Line 8. OS has a data type of List
Line 10. OR
Line 12. The query should search for records that include the field name “OS”
Line 13. the “OS” field must exactly match
Line 15. to the value “Windows Server 2019”
Line 14. OS has a data type of List
Line 17. AND
Line 20. the query should search for records that includes the field name “sourcetype”
Line 12. the “sourcetype” field must not match
Line 23. to the value “sentinel”
Line 22. sourcetype has a data type of List
Line 27-Line 30. Specifies pagination.
Query with OR and AND: Response
The response includes 2000 lines. Here is an abbreviated response.
The response includes:
All assets with an operating system of Windows Server 2019
All assets with an operating system of Windows Server 2020
And then filters to include only those assets from the first two criteria that also are not running SentinelOne.
{
"totalRecords": 250,
"data": [
{
"_id": "6461f106081577f5c85d98cb",
"_time": 1684139969,
"run_time": 1684139969,
"Asset_Name": "WIN-JG2A3JF7U0G",
"Last_Discovered_Datetime": 1684138517,
"MAC_Address": [
"00:50:56:85:db:0f"
],
"IP_Address": [
"10.64.71.20"
],
"Host_Name": [
"WIN-JG2A3JF7U0G"
],
"sourcetype": [
"sciencelogic_device"
],
},
{
"_id": "6461f106081577f5c85d98c7",
"_time": 1684139969,
"run_time": 1684139969,
"Asset_Name": "WIN-F9NU88H3VLE",
"Last_Discovered_Datetime": 1684138517,
"MAC_Address": [
"08:00:27:92:98:c1"
],
"IP_Address": [
"192.168.86.49"
],
"Host_Name": [
"WIN-F9NU88H3VLE"
],
"High_CVE": null,
"sourcetype": [
"sciencelogic_device"
],
}
],
"totalPages": 50,
"recordsPerPage": 5,
"page": 0
}
Python Query to Retrieve a List of Assets with macOS Operating System
import requests
import json
import time
url = "https://demo.lucidum.cloud/CMDB/v2/data/cmdb"
authToken = 'Bearer LLMcoobFjUAmCNBMftbg'
payload = {
"query": [
[
{
"searchFieldName": "Lucidum_OS_Type",
"operator": "in",
"type": "List",
"value": ["macOS"]
}
]
],
"table": "asset",
"paging": {
"page": 0,
"recordsPerPage": 5
}
}
def create_session():
s = requests.Session()
s.headers = {
'Content-Type': 'application/json',
'Authorization': authToken
}
return s
if __name__ == '__main__':
page = 0
result= []
sess = create_session()
while True:
payload['paging']['page'] = page
resp = sess.post(url, data=json.dumps(payload), verify=False)
data = resp.json()
result = result + data['data']
print("Total Result Records\t:", len(result))
print("Page\t\t:", data['page'])
if page < data['totalPages']:
page = page + 1
else:
break
time.sleep(1)
print("Total Result Records\t:", len(result))
Line 1 - Line 3. The code imports the requests, json, and time modules.
Line 5. Sets the variable “url” to “https://demo.lucidum.cloud/CMDB/v2/data/cmdb”
Line 6. Set the variable “authToken” to “Bearer swMcoobFjUAmCNBMftbj”
Line 8 - Line 24. Sets the “payload” dictionary to define the query parameters and the table parameter:
The query should search for records that include the field name “Lucidum_OS_Type”
The “Lucidum_OS_Type” field must include
the value “macOS”
Lucidum_OS_Type has a data type of “List”
The table parameter is asset. We will query the “asset” table in the Lucidum database
The paging parameter is set to starts at “0” (zero) and includes 5 records per page.
Line 26 - Line 32. Define the create_session () method. This method creates a requests.Session object and defines the session header to include the session object, the authToken value, and specifies data type of JSON. These are the header elements required by the https://demo.lucidum.cloud/CMDB/v2/data/cmdb endpoint.
Line 35. The code defines a variable called “page and initializes the variable to be “0”
Line 36. The code defines a variable called “result“ as an empty list of records.
Line 37. The code uses the create_session() method to define a variable (session object) called “sess”.
Line 38. This code creates an infinite loop (while True:) that will run until the page number is greater than the total number of pages.
Line 39. The code defines the “page” parameter of the “payload” dictionary, with 'paging' as its key and 'page' as its value.
Line 40. The code then sends a POST request with the sess.post method. The POST uses the previously specified URL and includes the previously defined value of “payload” (the query parameter, table parameter, and paging parameter).
Line 41. The code uses the resp.json method to retrieve the JSON response from the POST request and assigns the stores the response value in the variable “data”
Line 42. The code appends the value of “data” to the “results” list. The loop continues until all pages of data have been retrieved.
Line 43. The script uses the print() function to print the total number of records in the result list and the current page number.
Line 44- Line 48. If the current page number is less than the total number of pages in the response, it increments the page variable by 1 and continues to the next iteration of the loop. Otherwise, it breaks out of the loop.
Line 49 - Line 50. The script then waits for 1 second using the time.sleep() function and prints the total number of records in the result list again.
Locate Assets with No Endpoint Protection or Out-of-Date Agent
This example queries the raw data directly from an endpoint protection data source and finds assets where the endpoint protection is not updated OR where endpoint protection is not installed.
{
"table":"asset",
"query":[
[
{
"searchFieldName":"EP_Not_Updated",
"operator":"==",
"type":"Binary",
"value":"True"
},
{
"searchFieldName":"EP_Not_Installed",
"operator":"==",
"type":"Binary",
"value":"True"
}
]
],
"paging": {
"page": 0,
"recordsPerPage": 5
}
}
Note that the body uses JSON syntax. For information on JSON syntax, see https://www.w3schools.com/js/js_json_syntax.asp
Line 2. Define the table parameter. We will query the “asset” table in the Lucidum database
Line 3. Define the query parameter
Line 6. The query should search for records that include the field name “EP_Not_Updated”
Line 7. the “EP_Not_Updated” field must match
Line 9. to the value “True”
Line 8. EP_Not_Updated has a data type of Binary
Line 10. OR
Line 12. The query should search for records that include the field name “EP_Not_Installed”
Line 13. the “EP_Not_Installled” field must match
Line 15. to the value “True”
Line 14. EP_Not_Installed has a data type of Binary
Line 19-Line 21. Specifies pagination.
Locate Assets with Public-Facing Ports Open
This example find assets with public-facing open ports.
{
"table":"asset",
"query":[
[
{
"searchFieldName":"EXT_Open_Ports",
"operator":"exists",
"type":"List",
"value":"yes"
}
]
],
"paging": {
"page": 0,
"recordsPerPage": 5
}
}
Note that the body uses JSON syntax. For information on JSON syntax, see https://www.w3schools.com/js/js_json_syntax.asp
Line 2. Define the table parameter. We will query the “asset” table in the Lucidum database
Line 3. Define the query parameter
Line 6. The query should search for records that include the field name “EXT_Open_Ports”
Line 7. the “EXT_Open_Ports” field must exist
Line 8. EXT_Open_Ports has a data type of List
Line 13-Line 15. Specifies pagination.
Locate Assets with SSL Certificates Due to Expire Soon
This example searches for SSL certificates that will expire within the next 90 days.
{
"table":"asset",
"query":[
[
{
"searchFieldName":"Lucidum_Asset_Type",
"operator":"match",
"type":"String",
"value":"Certificate"
}
],
{
"searchFieldName":"Expired_Datetime",
"operator":"within future",
"type":"Datetime",
"value":"90,days"
}
]
],
"paging": {
"page": 0,
"recordsPerPage": 5
}
}
Line 2. Define the table parameter. In this example, we will query the “asset” table
Line 3. Define the query parameter.
Line 6. the record must include the field name “Lucidum_Asset_Type”
Line 7. the “Lucidum_Asset_Type” field contains an exact match
Line 9. to the value “Certificate”
Line 8. Lucidum_Asset_Type has a data type of String
Line 11. AND
Line 13. the record must include the field name “Expired_Datetime”
Line 14. the “Expired_Datetime” field must fall “within future”
Line 16. to the value “90,days”. For details about syntax for Datetime fields, see Endpoints for Assets and Users | Datetime-Fields (https://docs.lucidum.io/lucidum-help-center/latest/public/endpoints-for-lucidum-api-v2#EndpointsforLucidumAPIv2-DatetimeFields ).
Line 15. Expire_Datetime has a data type of Datetime
Lines 20-22. Specify pagination