Investigator API¶
The Investigator API provides read-only access to alerts and detections, enabling integration with security platforms such as SOAR systems for case creation, status synchronization, and third-party data enrichment.
Key features¶
The Investigator API includes the following features:
GraphQL-based queries: Provides flexible and precise data retrieval.
API key authentication: Secure access with API keys fully managed from the Investigator UI.
Efficient data retrieval: Supports pagination and filtering to manage large datasets.
SOAR/SIEM integration: Connects with security automation platforms to streamline workflows.
Before you begin¶
To get started with the Investigator API, you will need the following:
API Endpoint: The API is accessible at https://api.investigator.corelight.com/graphql.
Schema: It uses a GraphQL schema to structure queries.
Authentication: You need an API key for all requests (see the next section).
Permissions: Your account must have Admin privileges to manage API keys.
Limit: Be aware that Investigator supports only one active API key. Creating or rotating a key revokes the previous one.
Authentication and API key management¶
To use the Investigator API, you must authenticate each HTTP request with an API key. You manage this key in the Investigator General Settings and it must be included in the request header.
Note
API key creation, rotation, and revocation are performed in the Investigator UI. Tools like curl, Postman, or GraphQL clients are used only to send authenticated GraphQL queries to the API.
Managing your API key¶
API keys are managed under General Settings | API Keys in the Investigator UI. You must have admin privileges.
You can:
Create a new API key to initiate access.
Rotate an existing key to enhance security or replace an exposed key.
Revoke a key that’s no longer needed or may have been compromised.
Important
Only one API key can exist at a time. Creating or rotating a key will revoke the previous key. Be sure to update any systems using the old key.
Create an API key¶
To generate a new API key:
Go to System Settings | General Settings.
Under API Keys, click New Key.
Enter a name or description for the key.
Read-only permissions for Detections and Alerts are enabled by default in v1.0.0.
Click Create Key and save it immediately.
Note
The API key is shown only once. Copy and store it securely.
Rotate an API key¶
Rotate a key to replace it, such as when it has been exposed or is due for renewal:
Go to General Settings | API Keys.
Locate your existing key and click the Rotate icon.
Click Generate New Key.
Note
The old key is immediately revoked. Systems using it must be updated with the new key. This action cannot be undone.
Revoke an API key¶
Revoke a key to permanently disable it, especially if it is no longer in use:
Go to General Settings | API Keys.
Locate the key to revoke.
Click the Delete icon and confirm by clicking Revoke Key.
Note
Once revoked, the key is permanently invalid. All requests using it will fail.
Quickstart guide¶
This Quickstart guide will walk you through making your first successful API call using the provided Python script.
Prerequisites¶
You must have Python 3.x installed on your system.
You need an active API key.
Step 1: Get your API key¶
Before you begin, you must have an API key. Follow the instructions in the Authentication and API Key Management to create and securely store your key.
Step 2: Save the script¶
The following Python script queries for alerts, detections, and alert metadata. Copy the following code and save it in a file named quickstart.py
.
import requests
import json
# The official endpoint for the Investigator API
GRAPHQL_ENDPOINT = "https://api.investigator.corelight.com/graphql"
# IMPORTANT: Replace "your-api-key" with your actual key below
API_KEY = "your-api-key"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}"
}
def run_query(query, variables=None, query_name=""):
"""Sends a GraphQL query and prints the response."""
print(f"--- Running Query: {query_name} ---")
payload = {"query": query}
if variables:
payload["variables"] = variables
try:
response = requests.post(GRAPHQL_ENDPOINT, headers=headers, json=payload, timeout=30)
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
print(json.dumps(response.json(), indent=2))
except requests.exceptions.HTTPError as http_err:
print(f"HTTP error occurred: {http_err}")
print(f"Response Text: {response.text}")
except Exception as err:
print(f"An error occurred: {err}")
finally:
print("-" * (len(query_name) + 20) + "\n")
# 1. Query: alerts
alerts_query = """
query Alerts($alert_filter: AlertFilterInput, $offset: Int, $size: Int, $sort: [SortParameterInput]) {
alerts(alert_filter: $alert_filter, offset: $offset, size: $size, sort: $sort) {
alerts {
alert_id
alert_info { alert_name alert_type content_id }
alert_timestamp { start end observed ttl }
score
false_positive
}
page_info {
offset
size
total_items
sort { sort_by sort_dir }
}
}
}
"""
alerts_variables = {
"alert_filter": {
"score": {"gte": 5},
"alert_info_list": [{"alert_name": "Suspicious Login"}]
},
"offset": 0,
"size": 5,
"sort": [{"sort_by": "score", "sort_dir": "desc"}]
}
run_query(alerts_query, alerts_variables, query_name="Alerts")
# 2. Query: detections
detections_query = """
query Detections($detection_filter: DetectionFilterInput, $offset: Int, $size: Int, $sort: [SortParameterInput]) {
detections(detection_filter: $detection_filter, offset: $offset, size: $size, sort: $sort) {
detections {
detection_id
alert_info { alert_name alert_type content_id }
alert_entity { entity_id entity_name entity_type entity_category }
detection_status
detection_timestamp { start end }
rank { severity }
}
page_info {
offset
size
total_items
sort { sort_by sort_dir }
}
}
}
"""
detections_variables = {
"detection_filter": {
"severity": {"gte": 3},
"detection_statuses": ["open"]
},
"offset": 0,
"size": 5,
"sort": [{"sort_by": "detection_id", "sort_dir": "asc"}]
}
run_query(detections_query, detections_variables, query_name="Detections")
# 3. Query: alertMetadataList
alert_metadata_query = """
query AlertMetadataList($alert_metadata_filter: AlertMetadataFilterInput, $offset: Int, $size: Int, $sort: [SortParameterInput]) {
alertMetadataList(alert_metadata_filter: $alert_metadata_filter, offset: $offset, size: $size, sort: $sort) {
alert_metadata_list {
id
title
content_id
severity
active
category
updated_timestamp
}
page_info {
offset
size
total_items
sort { sort_by sort_dir }
}
}
}
"""
alert_metadata_variables = {
"alert_metadata_filter": {
"active_statuses": [True],
"severity": {"gte": 2}
},
"offset": 0,
"size": 5,
"sort": [{"sort_by": "updated_timestamp", "sort_dir": "desc"}]
}
run_query(alert_metadata_query, alert_metadata_variables, query_name="Alert Metadata")
Step 3: Configure your API key¶
Open quickstart.py
in an editor and replace the placeholder your-api-key
with the key you generated.
Step 4: Run the script¶
Open your terminal, navigate to the directory where you saved the file, and run:
python quickstart.py
Step 5: Review the results¶
The script prints three JSON objects to your console for Alerts, Detections, and Alert Metadata. This confirms you have successfully connected to the Investigator API. You can now adapt this script for your own use cases.
Common use cases and workflows¶
This section provides examples of how the Investigator API can integrate into common security workflows.
SOAR integration for case management¶
Goal: Automatically create and update cases in a SOAR platform like Splunk SOAR, Palo Alto XSOAR, or Torq.
Target Audience: SOAR Engineer, Automation Specialist.
Workflow:
Periodically poll the
detections
query for new items wheredetection_status
isopen
. You can use theearliest_start_timestamp
filter to avoid re-fetching old data.For each new detection, use its
detection_id
,alert_info
,alert_entity
, andrank.severity
to create a new case in your SOAR.Store the mapping between the
detection_id
and your SOAR case ID. This allows you to synchronize status updates or add new alerts to existing cases later.
SIEM data enrichment¶
Goal: Add deeper context to events in your SIEM (for example, Splunk, Elastic, Microsoft Sentinel).
Target Audience: Security Analyst, SIEM Engineer.
Workflow:
When a notable event involving a specific IP address or hostname appears in your SIEM, trigger an enrichment script.
The script calls the
alerts
query, using thealert_entity_list
filter to find all other Investigator alerts involving that same entity.The results can be added back to the original SIEM event as comments or appended data, giving your analysts immediate access to related Corelight findings without leaving their primary tool.
Custom triage with dashboards or notifications¶
Goal: Build a custom dashboard or notification system to highlight the most critical threats first.
Target Audience: Detection Engineer, Security Operations Lead.
Workflow:
Regularly query the
detections
endpoint, sorting the results byrank.severity
in descending order ("sort_dir": "desc"
).In your application, you can apply additional business logic. For example, you could increase the priority of a high-severity detection if the
alert_entity
involved is tagged as a high-value asset in your environment.Send a high-priority notification (for exaple, to Slack or PagerDuty) with key details and a link back to the detection in the Investigator UI.
Making API requests¶
You can call the Investigator API by sending a POST
request to the GraphQL endpoint using any HTTP client that supports JSON.
Required headers¶
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Sample curl request¶
This example sends a simple query to fetch the alert_id
and score
for the 10 most recent alerts.
curl -X POST https://api.investigator.corelight.com/graphql \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "query { alerts(offset: 0, size: 10) { alerts { alert_id score } } }"
}'
Common tools¶
The following tools are commonly used to send GraphQL requests to the Investigator API:
Command line: curl
GUI-based: Postman (use the GraphQL tab)
GraphQL clients: Altair, Insomnia
Rate limits¶
To ensure fair usage and API stability, the Investigator API enforces the following rate limits:
Per minute: 100 requests
Per hour: 1500 requests
Per day: 36,000 requests
Exceeding these returns a 429 Too Many Requests
with a Retry-After
header.
Note
Only successful requests count against the rate limit.
Error handling¶
The API uses standard HTTP status codes to indicate success or failure. Common responses include:
400 Bad Request
: Malformed syntax401 Unauthorized
: Missing/invalid key403 Forbidden
: Insufficient permissions429 Too Many Requests
: Rate limit hit
API reference¶
This reference provides detailed information on all available queries, the objects they return, and the data structures. The Investigator API provides queries for retrieving alerts, detections, and alert metadata with filtering, pagination, and sorting capabilities.
The system supports multiple alert types including:
SuricataAlert: Alerts from the Suricata network security tool.
MlAlert: Alerts from supervised machine learning models.
CustomSearchRuleAlert: Alerts generated from user-defined search rules.
YaraAlert: Alerts from Yara for malware detection.
AnomalyAlert: Alerts from unsupervised machine learning for anomaly detection.
NoticeAlert: Alerts from Zeek Notices.
Alerts query¶
Retrieves a list of alerts. An Alert
is an interface that represents a single security event. Specific alert types (like SuricataAlert
, NoticeAlert
, AnomalyAlert
, CustomSearchRuleAlert
, MlAlert
, and YaraAlert
) implement this interface and may have additional fields.
Parameters¶
The following table describes the available parameters for filtering, paginating, and sorting alert results.
Parameter |
Type |
Description |
---|---|---|
|
|
An object containing filters for the query, such as by alert info, entities, timestamp, or score. |
|
|
The number of items to skip for pagination. Defaults to 0. |
|
|
The number of items to return per page. Max 100, defaults to 10. |
|
|
An array of objects to define sorting. Defaults to timestamp descending. |
Request¶
The following GraphQL query example retrieves the first five alerts with a score greater than or equal to 5, filtered by a specific alert name, and sorted by score.
query Alerts($alert_filter: AlertFilterInput, $offset: Int, $size: Int, $sort: [SortParameterInput]) {
alerts(alert_filter: $alert_filter, offset: $offset, size: $size, sort: $sort) {
alerts {
alert_id
alert_info { alert_name alert_type content_id }
alert_timestamp { start end observed ttl }
score
false_positive
}
page_info {
offset
size
total_items
sort { sort_by sort_dir }
}
}
}
Variables¶
This object defines the parameters used in the GraphQL query above, allowing for dynamic filtering, pagination, and sorting of alerts.
{
"alert_filter": {
"score": {
"gte": 5
},
"alert_info_list": [
{
"alert_name": "ETPRO JA3 Hash - Possible Ligolo Server/Golang Binary Response"
}
]
},
"offset": 0,
"size": 5,
"sort": [
{
"sort_by": "score",
"sort_dir": "desc"
}
]
}
Response¶
Example response showing a subset of the alert objects to illustrate structure and key fields.
{
"data": {
"alerts": {
"alerts": [
{
"alert_id": "cff115c9-1354-4995-bbaa-c248ecd36b36",
"alert_info": {
"alert_name": "ETPRO JA3 Hash - Possible Ligolo Server/Golang Binary Response",
"alert_type": "suricata_corelight",
"content_id": "SURI-2850023"
},
"alert_timestamp": {
"start": 1742770313,
"end": 1742770313,
"observed": 1742770313,
"ttl": 1750546313
},
"score": 6,
"false_positive": false
}
],
"page_info": {
"offset": 0,
"size": 5,
"total_items": 9999,
"sort": [
{
"sort_by": "score",
"sort_dir": "desc"
}
]
}
}
}
}
Detections query¶
Retrieves a list of detection objects, which are higher-level correlated security incidents.
Parameters¶
The following table describes the available parameters for filtering, paginating, and sorting detection results.
Parameter |
Type |
Description |
---|---|---|
|
|
An object containing filters for the query, such as status, severity, timestamps, assignees, or associated alert info. |
|
|
The number of items to skip for pagination. Defaults to 0. |
|
|
The number of items to return per page. Max 100, defaults to 10. |
|
|
An array of objects to define sorting. |
Request¶
The following query example retrieves open detections with a severity of 3 or higher, sorted by their ID.
query Detections($detection_filter: DetectionFilterInput, $offset: Int, $size: Int, $sort: [SortParameterInput]) {
detections(detection_filter: $detection_filter, offset: $offset, size: $size, sort: $sort) {
detections {
detection_id
alert_info { alert_name alert_type content_id }
alert_entity { entity_id entity_name entity_type entity_category }
detection_status
detection_timestamp { start end }
rank { severity }
}
page_info {
offset
size
total_items
sort { sort_by sort_dir }
}
}
}
Variables¶
This object specifies the parameters for the detection query, including filters for severity and status, as well as pagination and sorting options.
{
"detection_filter": {
"severity": {
"gte": 3
},
"detection_statuses": [
"open"
]
},
"offset": 0,
"size": 5,
"sort": [
{
"sort_by": "detection_id",
"sort_dir": "asc"
}
]
}
Response¶
Example response showing a subset of the detection objects to illustrate structure and key fields.
{
"data": {
"detections": {
"detections": [
{
"detection_id": "1ca01fd03b64be883b707b39383f1d80",
"alert_info": {
"alert_name": "SSL::Invalid_Server_Cert",
"alert_type": "notice",
"content_id": "SSL::Invalid_Server_Cert"
},
"alert_entity": {
"entity_id": "IP10.2.128.138",
"entity_name": "10.2.128.138",
"entity_type": "IP",
"entity_category": "source"
},
"detection_status": "open",
"detection_timestamp": {
"start": 1749881040,
"end": 9223372036854776000
},
"rank": {
"severity": 4
}
}
],
"page_info": {
"offset": 0,
"size": 5,
"total_items": 7,
"sort": [
{
"sort_by": "detection_id",
"sort_dir": "asc"
}
]
}
}
}
}
AlertMetadataList query¶
Retrieves a list of alert metadata definitions, which describe the nature of different alert types.
Parameters¶
The following table describes the available parameters for filtering, paginating, and sorting Alert Metadata definitions.
Parameter |
Type |
Description |
---|---|---|
|
|
An object containing filters for the query, including titles, content IDs, status, category, and severity. |
|
|
The number of items to skip for pagination. Defaults to 0. |
|
|
The number of items to return per page. Max 100, defaults to 10. |
|
|
An array of objects to define sorting. |
Request¶
The following query example retrieves active AlertMetadataList definitions with a severity of 2 or higher, sorted by the most recently updated.
query AlertMetadataList($alert_metadata_filter: AlertMetadataFilterInput, $offset: Int, $size: Int, $sort: [SortParameterInput]) {
alertMetadataList(alert_metadata_filter: $alert_metadata_filter, offset: $offset, size: $size, sort: $sort) {
alert_metadata_list {
id
title
content_id
severity
active
category
updated_timestamp
}
page_info {
offset
size
total_items
sort { sort_by sort_dir }
}
}
}
Variables¶
This object provides the parameters for the AlertMetadataList query, allowing for filtering by active status and severity, alongside pagination and sorting.
{
"alert_metadata_filter": {
"active_statuses": [
true
],
"severity": {
"gte": 2
}
},
"offset": 0,
"size": 5,
"sort": [
{
"sort_by": "updated_timestamp",
"sort_dir": "desc"
}
]
}
Response¶
Example response showing a subset of the metadata objects to illustrate structure and key fields.
{
"data": {
"alertMetadataList": {
"alert_metadata_list": [
{
"id": "847f532b-ad34-4c1f-b40f-e6c2fc260f35",
"title": "MOVEit Authentication bypass SSH",
"content_id": "847f532b-ad34-4c1f-b40f-e6c2fc260f35",
"severity": 10,
"active": true,
"category": null,
"updated_timestamp": 1749578764
}
],
"page_info": {
"offset": 0,
"size": 5,
"total_items": 51016,
"sort": [
{
"sort_by": "updated_timestamp",
"sort_dir": "desc"
}
]
}
}
}
}
Response type reference¶
This section uses clear tables to show each API object’s fields, types, and descriptions.
Top-level objects¶
This table shows the main data returned by the alerts, detections, and alertMetadataList queries.
Object |
Attribute |
Type |
Description |
---|---|---|---|
Alerts |
|
|
An array of alert objects. |
|
|
Pagination information for the result set. |
|
Detections |
|
|
An array of detection objects. |
|
|
Pagination information for the result set. |
|
AlertMetadataList |
|
|
An array of alert metadata objects. |
|
|
Pagination information for the result set. |
Alert object¶
The following table describes the fields returned for the Alert object.
Attribute |
Type |
Description |
---|---|---|
|
|
The primary entity (e.g., IP, Host) associated with the alert. |
|
|
Unique identifier for the alert. A |
|
|
An object containing the alert name, type, and content ID. |
|
|
An object containing start, end, observed, and TTL timestamps. |
|
|
A list of entities that were the destination in the alert. |
|
|
A list of event identifiers associated with the alert. |
|
|
Indicates if the alert has been marked as a false positive. |
|
|
A list of MITRE ATT&CK tactic IDs associated with the alert. |
|
|
A list of MITRE ATT&CK technique IDs associated with the alert. |
|
|
A list of other entities related to this alert. |
|
|
The calculated severity score of the alert. |
|
|
A list of entities that were the source in the alert. |
Detection object¶
The following table describes the fields returned for the Detection object.
Attribute |
Type |
Description |
---|---|---|
|
|
The primary entity associated with the detection. |
|
|
The primary alert information that defines the detection. |
|
|
Information on which user is assigned to this detection. |
|
|
The Unix timestamp when the detection was first created. |
|
|
Unique identifier for the detection. |
|
|
The workflow status of the detection (e.g., open, closed). |
|
|
The start and end time of the detection window. |
|
|
The earliest start time among all alerts within the detection. |
|
|
Information related to the escalation of the detection. |
|
|
The latest start time among all alerts within the detection. |
|
|
MITRE ATT&CK tactic and technique information for the detection. |
|
|
A list of MITRE ATT&CK tactic IDs associated with the detection. |
|
|
A list of MITRE ATT&CK technique IDs associated with the detection. |
|
|
An object containing the detection’s severity level. |
|
|
The total number of alerts grouped within this detection. |
|
|
Information about when the detection was last updated and by whom. |
AlertMetadata object¶
The following table describes the fields returned for the AlertMetadata object.
Attribute |
Type |
Description |
---|---|---|
|
|
Whether this alert rule is currently active and generating alerts. |
|
|
Author of the alert definition. |
|
|
The category of the alert (e.g., suricata_corelight). |
|
|
An object containing guidance for alert handling. |
|
|
A unique content identifier for the alert type. |
|
|
CVE reference if applicable. |
|
|
Creation date of the metadata. |
|
|
A detailed description of what the alert signifies. |
|
|
Unique identifier for the metadata entry. |
|
|
MITRE ATT&CK tactic and technique information. |
|
|
A list of reference links. |
|
|
The underlying alert rule definition. |
|
|
The default severity level of the alert, from 1-10. |
|
|
An object containing detailed severity settings. |
|
|
The status of the metadata entry. |
|
|
The human-readable name of the alert rule. |
|
|
User who last updated the metadata. |
|
|
The Unix timestamp of the last update to this definition. |
Common and supporting types¶
The following table lists shared types and enums used across multiple responses (e.g. PageInfo, AlertStatus).
Object |
Attribute |
Type |
Description |
---|---|---|---|
AlertEntity |
|
|
A unique system ID for the entity. |
|
|
The value of the entity (e.g.,
|
|
|
|
The type of entity (e.g., IP, HOST, DOMAIN). |
|
|
|
Whether the entity was the source or destination. |
|
AlertInfo |
|
|
The display name of the alert. |
|
|
The source of the alert (e.g.,
|
|
|
|
A unique content identifier for the alert type. |
|
DetectionRank |
|
|
Indicates if a custom severity is being used. |
|
|
The severity level of the detection. |
|
PageInfo |
|
|
The current offset in the result set. |
|
|
The number of items returned in the current page. |
|
|
|
The total number of items available for the query. |
|
|
|
The sorting parameters applied to the query. |
API schema¶
This schema defines the public APIs for Investigator. It provides queries for retrieving alerts, detections, and alert metadata with filtering, pagination, and sorting capabilities.
The system supports multiple alert types including:
Suricata alerts: Suricata network security alerts.
ML-based alerts: Alerts generated by supervised machine learning models.
Custom search rule alerts: Alerts from custom search rules.
Yara alerts: Malware detection alerts using Yara rules.
Anomaly alerts: Alerts from unsupervised anomaly detection systems.
Notice alerts: Alerts from Zeek notices.
Root queries¶
This section defines the top-level GraphQL queries available in the Investigator API, serving as the entry points for data retrieval.
"""
Root query type containing all available queries
All queries require API key authentication
"""
type Query {
"""
Retrieve alerts with optional filtering, pagination, and sorting
Args:
alert_filter: Optional filter criteria for alerts
offset: Number of items to skip (for pagination)
size: Number of items to return (for pagination)
sort: Array of sort parameters
Returns:
Alerts object containing alert list and pagination info
"""
alerts(alert_filter: AlertFilterInput, offset: Int, size: Int, sort: [SortParameterInput]): Alerts @api_key
"""
Retrieve detections with optional filtering, pagination, and sorting
Args:
detection_filter: Optional filter criteria for detections
offset: Number of items to skip (for pagination)
size: Number of items to return (for pagination)
sort: Array of sort parameters
Returns:
Detections object containing detection list and pagination info
"""
detections(detection_filter: DetectionFilterInput, offset: Int, size: Int, sort: [SortParameterInput]): Detections @api_key
"""
Retrieve alert metadata with optional filtering, pagination, and sorting
Args:
alert_metadata_filter: Optional filter criteria for alert metadata
offset: Number of items to skip (for pagination)
size: Number of items to return (for pagination)
sort: Array of sort parameters
Returns:
AlertMetadataList object containing metadata list and pagination info
"""
alertMetadataList(alert_metadata_filter: AlertMetadataFilterInput, offset: Int, size: Int, sort: [SortParameterInput]): AlertMetadataList @api_key
}