Differential Analysis API
Overview
Audit and Remediation is a real-time query and remediation solution that gives teams faster, easier access to audit and change the system state of endpoints across their organization. It contains three components; Live Response, Live Query, and Differential Analysis. This document describes the Differential Analysis API.
Differential Analysis provides the ability to compare and understand the changes between two Live Query runs. The differential is calculated based on point-in-time snapshots. These features answer the question, “What changed on endpoints, and when?”.
Key Features
- Compare current with previous point-in-time snapshots of endpoints to understand what was changed on them
- Export results asynchronously
Use Cases
- Monitor files, folders, and registry keys with a low change probability
- Monitor for changes or modifications to the configuration of endpoints
- Monitor for unexpected installations and changes to existing browser extensions
- Monitor for changes in security settings such as drive encryption, password standards, service stoppages, RDP events and more
Requirements
- Carbon Black Cloud Audit and Remediation
- Devices with Carbon Black Cloud Sensor Installed. For a full list of supported Sensor versions and OSs, click here
- All API calls require an API key with appropriate permissions, see Authentication for details
Rate Limits
These rate limits apply on a per-org basis.
- 350 requests / 5 mins for Sync API
- 100 requests / 5 mins for Async API
Authentication
Determine whether you use Carbon Black Cloud or VMware Cloud Services Platform to manage identity and authorization, or see the Carbon Black Cloud API Access Guide for complete instructions.Carbon Black Cloud Managed Identity and Authentication
Customize your access to the Carbon Black Cloud APIs with Role-Based Access Control; All APIs and Services authenticate via API Keys. To access the data in Carbon Black Cloud via API, you must set up a key with the correct permissions for the calls you want to make and pass it in the HTTP Headers.
Environment
Available on majority of environments; Use the Carbon Black Cloud Console URL, as described here.
API Route
Replace the {cbc-hostname} and {org_key} with the URL of your Environment and the org_key for your specific Org.
- {cbc-hostname}/livequery/v1/orgs/{org_key}/differential
Access Level
Before you create your API Key, you need to create a "Custom" Access Level including each category:
- Live Query > Manage queries > livequery.manage, allow permission to
READ
API Key
When creating your API Key, use the Access Level Type of "Custom" and select the Access Level you created. Details on constructing and passing the API Key in your requests are available here.
Cloud Services Platform Managed Identity and Authentication
Customize your access to the Carbon Black Cloud APIs with OAuth Access Control; API access is controlled using OAuth apps or User API Tokens. This is currently limited to the UK Point of Presence and AWS GovCloud (US).
Environment
Available on
Prod UK
and AWS GovCloud (US)
. Full list of environments is available here; Use the Carbon Black Cloud Console URL from Cloud Services Platform, as described here.
API Route
Replace the {cbc-hostname} and {org_key} with the URL of your Environment and the org_key for your specific Org.
- {cbc-hostname}/livequery/v1/orgs/{org_key}/differential
Access Level
Before you create your OAuth App, you need to create a custom Role with the following permissions under IDENTITY & ACCESS MANAGEMENT > Roles > VMware Carbon Black Cloud:
- _API.Live.Query:livequery.Manage, allow permission to
READ
API Authentication
The Cloud Services Platform supports several authentication options, Access Token, API Token, and for backward compatibility, X-Auth-Token. To learn about the differences or how to use the authentication methods see the Authentication Guide.
Quick Start
Quick Start guides follow entire workflows for common scenarios using Differential Analysis API.
To perform a Differential Analysis, go through a Live Query API workflow to create the "point-in-time" snapshots of your endpoints or use existing ones. You can find a step-by-step Live Query guide under Live Query API > Quick Start > Automatically Recurring Query.
Start a Query Comparison with the id's you received from step 1.
Set
"count_only": true
to receive only the number of changes between the two runs (example .a), and "count_only": false
to receive the actual differential data (example .b).
POST https://defense.conferdeploy.net/livequery/v1/orgs/ABCD1234/differential/runs/_search
X-AUTH-TOKEN: "ABCDEFGHIJKLMNO123456789/ABCD123456"
Content-Type: "application/json"
Example .a
{
"count_only": true,
"criteria": {
"device_id": [ 11412673 ]
},
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal"
}
{
"org_key": "ABCD1234",
"results": [
{
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"newer_run_create_time": "2022-05-11T10:49:36.190Z",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal",
"older_run_create_time": "2022-05-11T10:47:48.952Z",
"diff_processed_time": 0.072,
"newer_run_not_responded_devices": [],
"older_run_not_responded_devices": [],
"diff_results": [
{
"device_id": 11412673,
"change_count": 1,
"added_count": 1,
"removed_count": 0,
"changes": null,
"older_run_row_count": 17,
"newer_run_row_count": 18
}
]
}
]
}
Example .b
{
"count_only": false,
"criteria": {
"device_id": [ 11412673 ]
},
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal"
}
{
"org_key": "ABCD1234",
"results": [
{
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"newer_run_create_time": "2022-05-11T10:49:36.190Z",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal",
"older_run_create_time": "2022-05-11T10:47:48.952Z",
"diff_processed_time": 0.051,
"newer_run_not_responded_devices": [],
"older_run_not_responded_devices": [],
"diff_results": [
{
"device_id": 11412673,
"change_count": 1,
"added_count": 1,
"removed_count": 0,
"changes": [
{
"action": "added",
"fields": [
{
"key": "name",
"value": "Enhancer for YouTube™"
},
{
"key": "path",
"value": "C:\\Users\\Administrator\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\6jmaljui.default-release\\extensions\\enhancerforyoutube@maximerf.addons.mozilla.org.xpi"
},
{
"key": "version",
"value": "2.0.113"
}
]
}
],
"older_run_row_count": 17,
"newer_run_row_count": 18
}
]
}
]
}
API Calls
Query Comparison
Compare two Live Query result sets asynchronously, and optionally export the response as JSON file. A result set can be two individual Live Query runs or any two ids from an automatically recurring query.
Note: Certain Rate Limits apply for Sync and Async queries.
Count Only
Set the request body parameter "count_only": true
to receive only the number of changes between the two runs (Count Only Example). This is the default behavior of the API.
Actual Changes
Set the request body parameter "count_only": false
to receive the actual differential data between the two runs (Actual Changes Example).
Export Results
Use the query parameters async
and format
to export the results as a JSON object asynchronously. The Query Comparison
call itself is not asynchronous - use its response. To receive the actual JSON results, you need to use the Job Service API. First, use the Get Job Details to get the status of the async job, then Download Job Output call to download the actual content (Export Results Example).
The Job Service API requires additional RBAC permissions.
Note: When comparing recurring Live Query runs, the older_run_id
is optional. If it is not specified, the run that is one earlier than newer_run_id will be the older_run_id.
API Permissions Required
Identity Manager | Permission (.notation name) | Operation(s) | Environment |
---|---|---|---|
Carbon Black Cloud | livequery.manage |
READ |
Majority of environments |
VMware Cloud Services Platform | _API.Live.Query:livequery.Manage.read |
N/A - included in permission name | Prod UK and AWS GovCloud (US) |
Request
POST {cbc-hostname}/livequery/v1/orgs/{org_key}/differential/runs/_search
Query Parameters
Both parameters are required when using the asynchronous functionality.
Parameter | Required | Values | Default |
---|---|---|---|
async | No | true |
true |
format | No | json |
json |
Request Body - application/json
{
"count_only": boolean,
"criteria": {
"device_id": [ integer ]
},
"newer_run_id": "<string>",
"older_run_id": "<string>"
}
Body Schema
Field | Definition | Data Type | Values |
---|---|---|---|
count_only | Specify whether the count of diff results per device or complete diff result must be returned. The default value is true , which means only the count will be returned |
Boolean | true , false |
criteria | Object that represents values that must be in the results | Object | criteria |
newer_run_id REQUIRED | id against which the older run id results will be compared | String | N/A |
older_run_id | This is optional if comparing two runs from a recurring query. If it is not specified, the run that is one earlier than newer_run_id and within the previous 24 hours will be the older_run_id .
If the prior run is more than 24 hours earlier, the message {"message":"Couldn't find run id older than newer run id {newer_run_id}.","error_code":"BAD_REQUEST"} will be received. |
String | N/A |
Response
Code | Description | Content-Type | Content |
---|---|---|---|
200 | Successfully retrieved differential analysis results | application/json | View example response below |
202 | Async job has been created | application/json | View example response below |
400 | The JSON body was malformed, or some part of the JSON body included an invalid value | N/A | N/A |
413 | The request parameters caused a large response body which cannot be handled | N/A | N/A |
429 | Service is busy processing other requests. | N/A | N/A |
Count Only
Examples
POST https://defense.conferdeploy.net/livequery/v1/orgs/ABCD1234/differential/runs/_search
X-AUTH-TOKEN: "ABCDEFGHIJKLMNO123456789/ABCD123456"
Content-Type: "application/json"
{
"count_only": true,
"criteria": {
"device_id": [ 11412673 ]
},
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal"
}
{
"org_key": "ABCD1234",
"results": [
{
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"newer_run_create_time": "2022-05-11T10:49:36.190Z",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal",
"older_run_create_time": "2022-05-11T10:47:48.952Z",
"diff_processed_time": 0.262,
"newer_run_not_responded_devices": [],
"older_run_not_responded_devices": [],
"diff_results": [
{
"device_id": 11412673,
"change_count": 1,
"added_count": 1,
"removed_count": 0,
"changes": null,
"older_run_row_count": 17,
"newer_run_row_count": 18
}
]
}
]
}
curl https://defense.conferdeploy.net/livequery/v1/orgs/ABCD1234/differential/runs/_search \
-X POST \
-H 'X-AUTH-TOKEN: ABCDEFGHIJKLMNO123456789/ABCD123456' \
-H 'Content-Type: application/json' \
-d '{
"count_only": true,
"criteria": {
"device_id": [ 11412673 ]
},
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal"
}'
{
"org_key": "ABCD1234",
"results": [
{
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"newer_run_create_time": "2022-05-11T10:49:36.190Z",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal",
"older_run_create_time": "2022-05-11T10:47:48.952Z",
"diff_processed_time": 0.262,
"newer_run_not_responded_devices": [],
"older_run_not_responded_devices": [],
"diff_results": [
{
"device_id": 11412673,
"change_count": 1,
"added_count": 1,
"removed_count": 0,
"changes": null,
"older_run_row_count": 17,
"newer_run_row_count": 18
}
]
}
]
}
import json
import requests
# DISCLAIMER: Never store your credentials within your code. The purpose of this script is to showcase
# the code's functionality and not to be implemented in a production scenario. Consider using the
# Carbon Black Cloud Python SDK, https://carbon-black-cloud-python-sdk.readthedocs.io/en/latest/authentication
# Replace org_key, base_url, device_id, x_auth_token, newer_run_id, older_run_id with your own data
org_key = 'ABCD1234'
base_url = 'https://defense.conferdeploy.net'
device_id = [ 11412673 ]
x_auth_token = 'ABCDEFGHIJKLMNO123456789/ABCD123456'
newer_run_id = 'qpopjb82whlmthlo0x1wrwcnoyxmrueu'
older_run_id = 'kibloccplynombvigcgtu2et2zayhzal'
req_body = {
"count_only": True,
"criteria": {
"device_id": device_id
},
"newer_run_id": newer_run_id,
"older_run_id": older_run_id
}
req_body_json = json.dumps(req_body)
req_url = f'{base_url}/livequery/v1/orgs/{org_key}/differential/runs/_search'
req_headers = {'Content-Type': 'application/json', 'X-AUTH-TOKEN': x_auth_token}
differential = requests.post(url=req_url, data=req_body_json, headers=req_headers)
print(differential.json())
{'org_key': 'ABCD1234',
'results': [{'diff_processed_time': 0.046,
'diff_results': [{'added_count': 1,
'change_count': 1,
'changes': None,
'device_id': 11412673,
'newer_run_row_count': 18,
'older_run_row_count': 17,
'removed_count': 0}],
'newer_run_create_time': '2022-05-11T10:49:36.190Z',
'newer_run_id': 'qpopjb82whlmthlo0x1wrwcnoyxmrueu',
'newer_run_not_responded_devices': [],
'older_run_create_time': '2022-05-11T10:47:48.952Z',
'older_run_id': 'kibloccplynombvigcgtu2et2zayhzal',
'older_run_not_responded_devices': []}]}
Actual Changes
Examples
POST https://defense.conferdeploy.net/livequery/v1/orgs/ABCD1234/differential/runs/_search
X-AUTH-TOKEN: "ABCDEFGHIJKLMNO123456789/ABCD123456"
Content-Type: "application/json"
{
"count_only": false,
"criteria": {
"device_id": [ 11412673 ]
},
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal"
}
{
"org_key": "ABCD1234",
"results": [
{
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"newer_run_create_time": "2022-05-11T10:49:36.190Z",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal",
"older_run_create_time": "2022-05-11T10:47:48.952Z",
"diff_processed_time": 0.062,
"newer_run_not_responded_devices": [],
"older_run_not_responded_devices": [],
"diff_results": [
{
"device_id": 11412673,
"change_count": 1,
"added_count": 1,
"removed_count": 0,
"changes": [
{
"action": "added",
"fields": [
{
"key": "name",
"value": "Enhancer for YouTube™"
},
{
"key": "path",
"value": "C:\\Users\\Administrator\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\6jmaljui.default-release\\extensions\\enhancerforyoutube@maximerf.addons.mozilla.org.xpi"
},
{
"key": "version",
"value": "2.0.113"
}
]
}
],
"older_run_row_count": 17,
"newer_run_row_count": 18
}
]
}
]
}
curl https://defense.conferdeploy.net/livequery/v1/orgs/ABCD1234/differential/runs/_search \
-X POST \
-H 'X-AUTH-TOKEN: ABCDEFGHIJKLMNO123456789/ABCD123456' \
-H 'Content-Type: application/json' \
-d '{
"count_only": false,
"criteria": {
"device_id": [ 11412673 ]
},
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal"
}'
{
"org_key": "ABCD1234",
"results": [
{
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"newer_run_create_time": "2022-05-11T10:49:36.190Z",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal",
"older_run_create_time": "2022-05-11T10:47:48.952Z",
"diff_processed_time": 0.062,
"newer_run_not_responded_devices": [],
"older_run_not_responded_devices": [],
"diff_results": [
{
"device_id": 11412673,
"change_count": 1,
"added_count": 1,
"removed_count": 0,
"changes": [
{
"action": "added",
"fields": [
{
"key": "name",
"value": "Enhancer for YouTube™"
},
{
"key": "path",
"value": "C:\\Users\\Administrator\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\6jmaljui.default-release\\extensions\\enhancerforyoutube@maximerf.addons.mozilla.org.xpi"
},
{
"key": "version",
"value": "2.0.113"
}
]
}
],
"older_run_row_count": 17,
"newer_run_row_count": 18
}
]
}
]
}
import json
import requests
# DISCLAIMER: Never store your credentials within your code. The purpose of this script is to showcase
# the code's functionality and not to be implemented in a production scenario. Consider using the
# Carbon Black Cloud Python SDK, https://carbon-black-cloud-python-sdk.readthedocs.io/en/latest/authentication
# Replace org_key, base_url, device_id, x_auth_token, newer_run_id, older_run_id with your own data
org_key = 'ABCD1234'
base_url = 'https://defense.conferdeploy.net'
device_id = [ 11412673 ]
x_auth_token = 'ABCDEFGHIJKLMNO123456789/ABCD123456'
newer_run_id = 'qpopjb82whlmthlo0x1wrwcnoyxmrueu'
older_run_id = 'kibloccplynombvigcgtu2et2zayhzal'
req_body = {
"count_only": False,
"criteria": {
"device_id": device_id
},
"newer_run_id": newer_run_id,
"older_run_id": older_run_id
}
req_body_json = json.dumps(req_body)
req_url = f'{base_url}/livequery/v1/orgs/{org_key}/differential/runs/_search'
req_headers = {'Content-Type': 'application/json', 'X-AUTH-TOKEN': x_auth_token}
differential = requests.post(url=req_url, data=req_body_json, headers=req_headers)
print(differential.json())
{'org_key': 'ABCD1234',
'results': [{'diff_processed_time': 0.044,
'diff_results': [{'added_count': 1,
'change_count': 1,
'changes': [{'action': 'added',
'fields': [{'key': 'name',
'value': 'Enhancer '
'for '
'YouTube™'},
{'key': 'path',
'value': 'C:\\Users\\Administrator\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\6jmaljui.default-release\\extensions\\enhancerforyoutube@maximerf.addons.mozilla.org.xpi'},
{'key': 'version',
'value': '2.0.113'}]}],
'device_id': 11412673,
'newer_run_row_count': 18,
'older_run_row_count': 17,
'removed_count': 0}],
'newer_run_create_time': '2022-05-11T10:49:36.190Z',
'newer_run_id': 'qpopjb82whlmthlo0x1wrwcnoyxmrueu',
'newer_run_not_responded_devices': [],
'older_run_create_time': '2022-05-11T10:47:48.952Z',
'older_run_id': 'kibloccplynombvigcgtu2et2zayhzal',
'older_run_not_responded_devices': []}]}
Export Results
Examples
POST https://defense.conferdeploy.net/livequery/v1/orgs/{org_key}/differential/runs/_search?async=true&format=json
X-AUTH-TOKEN: "ABCDEFGHIJKLMNO123456789/ABCD123456"
Content-Type: "application/json"
{
"count_only": false,
"criteria": {
"device_id": [ 11412673 ]
},
"newer_run_id": "ztpbsoapz7zsa186uhefjxdpu8o6yo6z",
"older_run_id": "0tm25lpeojq2lfcwef2q18bsfuzeiaud"
}
{
"ref_url": "https://defense.conferdeploy.net/jobs/v1/orgs/ABCD1234/jobs/12345",
"job_id": 12345
}
curl https://defense.conferdeploy.net/livequery/v1/orgs/{org_key}/differential/runs/_search?async=true&format=json \
-X POST \
-H 'X-AUTH-TOKEN: ABCDEFGHIJKLMNO123456789/ABCD123456' \
-H 'Content-Type: application/json' \
-d '{
"count_only": false,
"criteria": {
"device_id": [ 11412673 ]
},
"newer_run_id": "qpopjb82whlmthlo0x1wrwcnoyxmrueu",
"older_run_id": "kibloccplynombvigcgtu2et2zayhzal"
}'
{
"ref_url": "https://defense.conferdeploy.net/jobs/v1/orgs/ABCD1234/jobs/12345",
"job_id": 12345
}
import json
import requests
# DISCLAIMER: Never store your credentials within your code. The purpose of this script is to showcase
# the code's functionality and not to be implemented in a production scenario. Consider using the
# Carbon Black Cloud Python SDK, https://carbon-black-cloud-python-sdk.readthedocs.io/en/latest/authentication
# Replace org_key, base_url, device_id, x_auth_token, newer_run_id, older_run_id with your own data
org_key = 'ABCD1234'
base_url = 'https://defense.conferdeploy.net'
device_id = [ 11412673 ]
x_auth_token = 'ABCDEFGHIJKLMNO123456789/ABCD123456'
newer_run_id = 'qpopjb82whlmthlo0x1wrwcnoyxmrueu'
older_run_id = 'kibloccplynombvigcgtu2et2zayhzal'
req_body = {
"count_only": False,
"criteria": {
"device_id": device_id
},
"newer_run_id": newer_run_id,
"older_run_id": older_run_id
}
req_body_json = json.dumps(req_body)
req_url = f'{base_url}/livequery/v1/orgs/{org_key}/differential/runs/_search?async=true&format=json'
req_headers = {'Content-Type': 'application/json', 'X-AUTH-TOKEN': x_auth_token}
differential = requests.post(url=req_url, data=req_body_json, headers=req_headers)
print(differential.json())
{'job_id': 12345,
'ref_url': 'https://defense.conferdeploy.net/jobs/v1/orgs/ABCD1234/jobs/12345'}
Fields
QueryComparisonRequest
Field | Definition | Data Type | Values |
---|---|---|---|
count_only |
Specify whether the count of diff results per device or complete diff result must be returned. The default value is true , which means only the count will be returned |
Boolean | true , false |
criteria |
Object that represents values that must be in the results | Object | criteria |
newer_run_id |
id against which the older run id results will be compared | String | N/A |
older_run_id |
This can be optional. If not specified, the previous run as compared to the primary will be chosen | String | N/A |
criteria
Field | Definition | Data Type | Values |
---|---|---|---|
device_id |
Allows the results to be filtered on device_id(s) | Array |
|
QueryComparisonResponse
Field | Definition | Data Type | Values |
---|---|---|---|
org_key |
Carbon Black organisation identifier | String | N/A |
results |
Array containing results object | Array | results |
results
Field | Definition | Data Type | Values |
---|---|---|---|
diff_processed_time |
The time it took to process the results in seconds and milliseconds | Double | Format: ss.SSS |
diff_results |
An object containing either count of changes only or count and actual diff results | Object | diff_results |
newer_run_create_time |
Timestamp of the primary run in ISO 8601 UTC format | String | Format: yyyy-MM-dd'T'HH:mm:ss.SSS'Z' |
newer_run_id |
id against which the older run id results will be compared | String | N/A |
newer_run_not_responded_devices |
Array | ||
older_run_create_time |
Timestamp of the older run id in ISO 8601 UTC format | String | Format: yyyy-MM-dd'T'HH:mm:ss.SSS'Z' |
older_run_id |
This can be optional. If not specified, the previous run as compared to the primary will be chosen. This can be optional if you are comparing reccuring runs only. | String | N/A |
older_run_not_responded_devices |
Array |
diff_results
Field | Definition | Data Type | Values |
---|---|---|---|
added_count |
Number of additive differences | Integer | N/A |
change_count |
Number of total change count - additive and subtractive | Integer | N/A |
changes |
Array containing objects with additive and subtractive changes metadata | Array | changes |
device_id |
Device identifier | Integer | N/A |
newer_run_row_count |
Number of total Live Query result objects in primary run | Integer | N/A |
removed_count |
Number of subtractive differences | Integer | N/A |
older_run_row_count |
Number of total Live Query result objects in older run | Integer | N/A |
changes
Field | Definition | Data Type | Values |
---|---|---|---|
action |
Indicates whether actions are additive or subtractive | String | ADDED , REMOVED |
fields |
Array of objects with metadata of the differential | Array | fields |
fields
Field | Definition | Data Type | Values |
---|---|---|---|
key |
Name of differential metadata | String | N/A |
value |
Content of differential metadata | String | N/A |
JobResponse
Field | Definition | Data Type | Values |
---|---|---|---|
ref_url |
Response object for async jobs contains URL with job id for the Job Service API. | String | N/A |
job_id |
id of the async job. Use id to query status, and results of the job | Integer | N/A |
Troubleshooting
Suggested fix: Verify the older run is within 24 hours of the newer run.
Assuming the scheduled query runs less frequently than every 24 hours, use the Search Previous Query Runs API to get the last two runs to compare.
Last modified on February 7, 2023