For console 2.17.4 · updated 2026-11-03
Your ByteMantle console already shows every attack your people's browsers met: the fake "verify you are human" pages, the phishing sign-ins, the commands a page tried to slip onto the clipboard, the incidents they formed. This guide is about getting that information out of the console and into the tools you already use — your SIEM, a spreadsheet, a ticket system, a dashboard, a script of your own, or an AI assistant that helps your security team.
There are two ways to do it, and most organizations use one or both:
| SIEM forwarding — the console sends | Read API — you ask | |
|---|---|---|
| In one sentence | Every new threat event goes to your SIEM within about a minute, without you writing any code. | Your script or tool asks the console for exactly the data it needs, whenever it needs it. |
| Good for | Splunk, Elastic, Microsoft Sentinel (through a Logic App), any system that accepts HTTPS webhooks or CEF | reports, exports to Excel / Power BI, opening tickets for new incidents, checks in your own monitoring, AI assistants |
| You set it up in | Admin → SIEM | Admin → API Keys |
| Plans | Pro, Business and Enterprise (and the trial) | Enterprise (and the trial) |
Only administrators of your organization can set up either one: the SIEM and API Keys pages are not in the menu of viewers and analysts. Both work only over HTTPS and only with your own organization's data.
Every command and script in this guide is run against a ByteMantle console before each release, and SIEM delivery is checked in all three formats by a receiver that inspects each delivery the way a SIEM does. The screenshots come from a demonstration console with sample data. If something does not work the way it is written here, tell us: that is a bug in the guide.
1. Send your threat events to your SIEM (10 minutes)
What you need: an HTTPS address on your SIEM side that accepts events, and the header it uses to authenticate (for Splunk, an HTTP Event Collector token).
- In the console, open Admin → SIEM.

- Under Add destination, fill in:
- Name — anything that tells you what it is, e.g. "Splunk production".
- Endpoint URL — your SIEM's HTTPS address. For Splunk it ends in
/services/collector/event(for examplehttps://splunk.example.com:8088/services/collector/event). - Format — Splunk HEC for Splunk; JSON batch for Elastic, a Logic App or any webhook; CEF lines for a syslog relay.
- Minimum severity — start with Medium or High if you only want what matters most.
- Auth header name / value — for Splunk:
AuthorizationandSplunk <your HEC token>. The value is stored encrypted and is never shown again, not even to you. - Event types — leave empty to receive every kind of threat event.

- Click Add destination, then Send test next to it. Your SIEM should receive one sample event within seconds. If it does not, the page shows the error your SIEM answered.

That is all. From now on the console sends new threat events every minute, in batches of up to 100. If your SIEM is unavailable, nothing is lost: the console tries again, waiting a little longer each time, and continues where it stopped. What exactly is sent, field by field, is in 4.8.
event_id: deduplicate on it.2. Your first API call (5 minutes)
What you need: a computer with curl (it is part of Windows 10 and 11, macOS and Linux).
Step 1 — create a key. In the console, open Admin → API Keys, give the key a name that says what will use it, and choose:
- Acts as: Viewer is enough for almost everything. Analyst is only needed if the key must also read the evidence text of events (the actual command a page tried to copy), and then you also tick Allow sensitive properties (with Viewer, the console refuses that box with a message).
- Data types: leave them all unticked to allow everything the role may read, or tick only what the integration needs.
- Allowed IP addresses: the address of the server that will use the key. Strongly recommended.
- Expires on: keys expire after a year by default; you can choose another date or none. The key works until the end of that day in the console's time zone.


Click Create key. The key appears once: copy it now and keep it in your password manager or secret store. The console keeps only a fingerprint of it, so nobody — not even ByteMantle — can show it to you again. If you lose it, create a new one and revoke the old one.


Step 2 — ask what you may read. Put the key in a variable (so it does not end up in your shell history twice) and call the catalog:
export BYTEMANTLE_KEY='ngk_paste-your-key-here'
curl -s -H "Authorization: Bearer $BYTEMANTLE_KEY" https://console.bytemantle.com/api/v1/catalog.phpYou get back the list of data types your key can read, with every field of each one (the full list is in 4.7).
Step 3 — ask for the high and critical events.
curl -s https://console.bytemantle.com/api/v1/query.php \
-H "Authorization: Bearer $BYTEMANTLE_KEY" -H "Content-Type: application/json" \
-d '{"type": "core.event",
"columns": ["event_time", "severity", "event_type", "site", "device.label", "action"],
"filters": [{"p": "severity", "op": "gte", "v": "high"}],
"sort": [{"p": "event_time", "dir": "desc"}],
"limit": 2}'The answer, exactly as the console sent it:
{
"ok": true,
"type": "core.event",
"columns": [
{"name": "event_time", "type": "datetime", "label": "Time"},
{"name": "severity", "type": "enum", "label": "Severity"},
{"name": "event_type", "type": "enum", "label": "Type"},
{"name": "site", "type": "domain", "label": "Site"},
{"name": "device__label", "type": "text", "label": "Label"},
{"name": "action", "type": "text", "label": "Action"}
],
"rows": [
{"event_time": "2026-11-03T12:44:02Z", "severity": "critical", "event_type": "service_worker", "site": "swu-zz.com",
"device__label": "Linux · Chrome · #0023", "action": "detected"},
{"event_time": "2026-11-03T12:44:02Z", "severity": "high", "event_type": "correlation", "site": "swu-zz.com",
"device__label": "Linux · Chrome · #0023", "action": "detected"}
],
"row_count": 2,
"limit": 2,
"truncated": false,
"next_cursor": "eyJvIjoyLCJxIjoiNTkwMTY3Njg0ZTg3NDYyYSJ9",
"took_ms": 2
}Three things to notice: device.label comes back as device__label (a field of a related object); times are always UTC; and next_cursor means more rows are waiting — 4.5 shows how to read them.
curl examples in Git Bash or WSL (the Command Prompt and PowerShell quote text differently), or use the Python recipes of section 3: they work the same on Windows, macOS and Linux.3. Recipes
Each recipe is complete: copy it, set BYTEMANTLE_KEY (and change console.bytemantle.com if your console has another address), and run it. The Python recipes need Python 3.9 or newer and the requests package (pip install requests).
3.1 Every event of the last 7 days into a CSV file (for Excel or Power BI)
import csv, os, requests
URL = "https://console.bytemantle.com/api/v1/query.php"
HEADERS = {"Authorization": "Bearer " + os.environ["BYTEMANTLE_KEY"]}
QUERY = {
"type": "core.event",
"columns": ["event_time", "severity", "event_type", "site", "url", "action", "blocked", "device.label", "incident_id"],
"filters": [{"p": "event_time", "op": "last", "v": {"n": 7, "unit": "day"}}],
"sort": [{"p": "event_time", "dir": "desc"}],
"limit": 1000,
}
rows, cursor = [], None
while True:
body = dict(QUERY, cursor=cursor) if cursor else QUERY
answer = requests.post(URL, json=body, headers=HEADERS, timeout=60).json()
if not answer["ok"]:
raise SystemExit(f"The console refused the query: {answer}")
rows += answer["rows"]
cursor = answer["next_cursor"]
if not cursor:
break
with open("bytemantle_events.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=[c["name"] for c in answer["columns"]])
writer.writeheader()
writer.writerows(rows)
print(f"{len(rows)} events written to bytemantle_events.csv")In Excel: Data → From Text/CSV and choose the file. In Power BI: Get data → Text/CSV. Run the script on a schedule (Task Scheduler, cron) to keep the file fresh.
core.event_summary, which holds hourly counts and answers much faster.3.2 A new ticket for every new incident
This script remembers the last incident it saw (in last_incident.txt) and prints every newer one as a line of JSON. Replace the print with a call to your ticket system's API (Jira, ServiceNow, a Teams or Slack webhook).
import json, os, pathlib, requests
URL = "https://console.bytemantle.com/api/v1/query.php"
HEADERS = {"Authorization": "Bearer " + os.environ["BYTEMANTLE_KEY"]}
STATE = pathlib.Path("last_incident.txt")
last_id = int(STATE.read_text()) if STATE.exists() else 0
answer = requests.post(URL, headers=HEADERS, timeout=60, json={
"type": "core.incident",
"columns": ["id", "title", "severity", "status", "site", "device.label", "first_seen_at", "last_seen_at", "event_count"],
"filters": [{"p": "id", "op": "gt", "v": last_id}, {"p": "severity", "op": "gte", "v": "high"}],
"sort": [{"p": "id", "dir": "asc"}],
"limit": 100,
}).json()
if not answer["ok"]:
raise SystemExit(f"The console refused the query: {answer}")
for incident in answer["rows"]:
print(json.dumps(incident)) # here: open the ticket
last_id = max(last_id, incident["id"])
STATE.write_text(str(last_id))
print(f"{len(answer['rows'])} new incident(s)")Run it every few minutes. It asks only for incidents newer than the last one it handled, so a ticket is never opened twice.
3.3 How many events per day, and of which kind
Two queries for a chart. Events per day, last 7 days:
{"type": "core.event",
"columns": [{"agg": "count", "as": "events"}],
"group": [{"p": "event_time", "bucket": "day", "as": "day"}],
"filters": [{"p": "event_time", "op": "last", "v": {"n": 7, "unit": "day"}}]}Events per kind, last 30 days, most frequent first:
{"type": "core.event",
"columns": ["event_type", {"agg": "count", "as": "events"}],
"group": ["event_type"],
"filters": [{"p": "event_time", "op": "last", "v": {"n": 30, "unit": "day"}}],
"sort": [{"by": "events", "dir": "desc"}]}Send either one the way step 3 of section 2 does (curl … -d '<the query>'). For long periods (months), ask core.event_summary instead of core.event: it holds hourly counts and answers much faster.
3.4 Open incidents, newest first
{"type": "core.incident",
"columns": ["id", "title", "severity", "status", "site", "device.label", "last_seen_at"],
"filters": [{"p": "status", "op": "in", "v": ["open", "investigating"]}],
"sort": [{"p": "last_seen_at", "dir": "desc"}],
"limit": 20}3.5 One event, by its number
The id is the number in the event's address in the console (index.php?p=event&id=…).
curl -s -H "Authorization: Bearer $BYTEMANTLE_KEY" \
"https://console.bytemantle.com/api/v1/query.php?type=core.event&id=241326&columns=event_time,severity,site,action"3.6 Receive the SIEM events in your own service
If you do not use a SIEM but want the events pushed to a service of your own, choose the JSON batch format in section 1 and point it at a small receiver like this one. The console only sends to HTTPS addresses, so run it behind your HTTPS reverse proxy (nginx, IIS, a cloud load balancer) and set the same secret in the destination's Auth header (Authorization / Bearer <your secret>).
import hmac, json, os
from http.server import BaseHTTPRequestHandler, HTTPServer
SECRET = os.environ["RECEIVER_SECRET"] # the value you also put in the console
PORT = int(os.environ.get("PORT", "8080"))
class Receiver(BaseHTTPRequestHandler):
def do_POST(self):
expected = "Bearer " + SECRET
if not hmac.compare_digest(self.headers.get("Authorization", ""), expected):
self.send_response(401); self.end_headers(); return
batch = json.loads(self.rfile.read(int(self.headers["Content-Length"])))
for event in batch["events"]:
print(event["time"], event["severity"], event["type"], event["site"], event["event_id"], flush=True)
self.send_response(204); self.end_headers() # any 2xx answer tells the console the batch arrived
HTTPServer(("0.0.0.0", PORT), Receiver).serve_forever()The console sends each batch until it gets a 2xx answer, so an event can occasionally arrive twice (for example after a network error): use event_id to recognise repeats.
3.7 ServiceNow: an incident for every ByteMantle incident
Most security teams track their work in ServiceNow. The simplest reliable way to connect ByteMantle to it is a small script that runs every few minutes: it asks ByteMantle for the open incidents, and creates an incident in ServiceNow for each one that is not there yet. ServiceNow's own Table API does the creating, so nothing has to be installed in ServiceNow.
What you need in ServiceNow (your ServiceNow administrator does this once):
- a user for the integration (for example
bytemantle.integration), with a password and the itil role, which allows it to read and create incidents; - your instance address, for example
https://yourcompany.service-now.com.
What the script does:
- each ByteMantle incident becomes one ServiceNow incident: it is marked with
correlation_id=bytemantle-<incident number>, and the script first asks ServiceNow whether that incident already exists, so running it again never creates duplicates; - severity becomes urgency and impact: critical → 1 / 1, high → 2 / 2, medium → 3 / 2 (low and info incidents are left out);
- the description carries the site, the browser, when it started, how many events, and a link back to the incident in the console.
import os, requests
CONSOLE = "https://console.bytemantle.com"
BYTEMANTLE = {"Authorization": "Bearer " + os.environ["BYTEMANTLE_KEY"]}
SNOW = os.environ["SNOW_INSTANCE"].rstrip("/") + "/api/now/table/incident" # e.g. https://yourcompany.service-now.com
SNOW_AUTH = (os.environ["SNOW_USER"], os.environ["SNOW_PASSWORD"])
JSON = {"Accept": "application/json"}
URGENCY_IMPACT = {"critical": ("1", "1"), "high": ("2", "2"), "medium": ("3", "2")}
answer = requests.post(CONSOLE + "/api/v1/query.php", headers=BYTEMANTLE, timeout=60, json={
"type": "core.incident",
"columns": ["id", "title", "severity", "site", "device.label", "first_seen_at", "event_count"],
"filters": [{"p": "status", "op": "in", "v": ["open", "investigating"]},
{"p": "severity", "op": "gte", "v": "medium"}],
"sort": [{"p": "id", "dir": "asc"}],
"limit": 100,
}).json()
if not answer["ok"]:
raise SystemExit(f"ByteMantle refused the query: {answer}")
created = 0
for incident in answer["rows"]:
correlation = f"bytemantle-{incident['id']}"
found = requests.get(SNOW, auth=SNOW_AUTH, headers=JSON, timeout=30,
params={"sysparm_query": f"correlation_id={correlation}", "sysparm_fields": "sys_id", "sysparm_limit": "1"})
found.raise_for_status()
if found.json()["result"]:
continue # already in ServiceNow
urgency, impact = URGENCY_IMPACT[incident["severity"]]
reply = requests.post(SNOW, auth=SNOW_AUTH, headers=JSON, timeout=30, json={
"short_description": "ByteMantle: " + incident["title"],
"description": (f"Severity: {incident['severity']}\n"
f"Site: {incident['site']}\n"
f"Browser: {incident['device__label']}\n"
f"First seen (UTC): {incident['first_seen_at']}\n"
f"Threat events: {incident['event_count']}\n"
f"In the ByteMantle console: {CONSOLE}/index.php?p=incident&id={incident['id']}"),
"urgency": urgency,
"impact": impact,
"correlation_id": correlation,
"correlation_display": "ByteMantle",
})
reply.raise_for_status()
created += 1
print(f"{created} incident(s) created in ServiceNow")Set BYTEMANTLE_KEY, SNOW_INSTANCE, SNOW_USER and SNOW_PASSWORD as environment variables (or in your secret store), and run it every 5 minutes with Task Scheduler or cron.
sn_si_incident with Security Incident Response). The script only needs the table name in the SNOW line changed; the field names above exist on both.Without a script. If your ServiceNow administrator prefers to receive events instead of fetching incidents, they can create a Scripted REST API in ServiceNow that accepts the JSON batch format of section 1 and add its address as a SIEM destination. The batch format is in 4.8. This sends every event (not incidents), so it suits event management better than incident tracking.
3.8 An AI assistant for your security team
An assistant that can make HTTP requests (a custom GPT action, a Copilot Studio connector, an agent you build) can use the Read API like any other client. Give it its own key, as Viewer, limited to the data types it needs (for example Incidents and Threat Events), with a low request limit and an expiry date. Describe the endpoints of 4.1 and the query format of 4.3 in its instructions, and it can answer questions like "which sites caused the most incidents this week?" from your own data. It can only read: no key can change anything in the console.
4. Reference
4.1 The three addresses
Every address starts with your console's address, for example https://console.bytemantle.com.
| Method and address | What it does |
|---|---|
GET /api/v1/catalog.php | What this key may read: the data types, each one's fields (name, type, operators, sorting, grouping, aggregates, possible values), how they relate, and your limits |
POST /api/v1/query.php | Runs a query (a JSON body, 4.3) and returns rows |
GET /api/v1/query.php?type=<type>&id=<id>&columns=<a,b,c> | One object by its id (columns is optional) |
4.2 Authentication
Send the key in the Authorization header: Authorization: Bearer ngk_…. If something on your side removes that header (some proxies do), send X-NextGen-API-Key: ngk_… instead.
- Keys start with
ngk_followed by 48 hexadecimal characters. - Your organization always comes from the key. A request never names an organization: a field called
tenantanywhere in a request is refused (tenant_not_allowed). - Requests over plain HTTP are refused. The API is for servers and scripts: it sends no CORS headers, so a web page in a browser cannot call it.
- A key can read, never change. It acts as a viewer or an analyst, never as an administrator: the audit log is not available through the API.
- Answers are JSON with
Cache-Control: private, no-store.
The catalog, for a key limited to one data type (yours lists every type your key may read; this one is complete):
{
"ok": true,
"role": "viewer",
"sensitive": false,
"types": [
{
"id": "core.user", "label": "Users", "primary_key": "id", "time_property": null, "search": [], "max_rows": 1000,
"properties": [
{"id": "id", "label": "ID", "type": "integer",
"operators": ["eq", "neq", "lt", "lte", "gt", "gte", "between", "in", "not_in", "is_null", "not_null"],
"sortable": true, "groupable": false, "time_buckets": [], "aggregates": []},
{"id": "username", "label": "Username", "type": "text",
"operators": ["eq", "neq", "in", "not_in", "contains", "starts_with", "ends_with", "is_null", "not_null", "is_empty", "not_empty"],
"sortable": true, "groupable": true, "time_buckets": [], "aggregates": []},
{"id": "display_name", "label": "Name", "type": "text",
"operators": ["eq", "neq", "in", "not_in", "contains", "starts_with", "ends_with", "is_null", "not_null", "is_empty", "not_empty"],
"sortable": true, "groupable": false, "time_buckets": [], "aggregates": []}
],
"relations": []
}
],
"aggregates": ["count", "count_distinct", "sum", "avg", "min", "max"],
"limits": {"default_rows": 100, "max_rows": 1000, "max_response_bytes": 2097152, "max_body_bytes": 262144,
"catalog_per_minute": 60, "query_per_minute": 120, "requests_per_day": 10000}
}A field can also carry "values" (the possible values of a list field such as severity), "sensitive": true (readable only by an analyst key allowed to read sensitive data) and "requires_time_filter": true.
4.3 The query format
A query is one JSON object. Only type is required.
| Field | What it means |
|---|---|
type | the data type (4.7) |
columns | the fields you want, in order. Each one is a field name; "device.label" for a field of a related object (the related objects of each type are in 4.7); {"p": "site", "as": "domain"} to rename; {"agg": "count", "as": "events"} or {"agg": "count_distinct", "p": "site", "as": "sites"} for a calculation over grouped rows. Without columns you get the type's default fields |
filters | a list of conditions that must all be true. A condition is {"p": field, "op": operator, "v": value} (operators in 4.4). To combine differently: {"any": [conditions]} = at least one is true, {"all": [conditions]} = all are true, {"not": condition} |
search | free text, looked for in the type's main text fields (the search list of each type in 4.7) |
group | fields to group by, or a time field cut into periods: {"p": "event_time", "bucket": "day", "as": "day"} (hour, day, week, month). Use calculations (agg) in columns |
sort | [{"p": field, "dir": "asc" or "desc"}], or {"by": name} for a renamed field or a calculation |
limit | rows per answer, from 1 to 1000 (default 100) |
cursor | the next_cursor of the previous answer, to read the next page (4.5) |
offset or page | instead of cursor: skip offset rows, or ask for page number page (starting at 1) of limit rows. Use only one of cursor, offset and page. The cursor is the better choice: it never skips or repeats rows when new events arrive |
Times in values and answers are UTC, written as ISO 8601 (2026-11-03T12:44:02Z). A calculation is available on a field only when the field lists it under aggregates in the catalog (the calculations are count, count_distinct, sum, avg, min, max).
A query that combines conditions:
{"type": "core.event",
"columns": ["id", "event_time", {"p": "site", "as": "domain"}, "incident.title"],
"filters": [
{"p": "event_time", "op": "last", "v": {"n": 30, "unit": "day"}},
{"any": [{"p": "event_type", "op": "in", "v": ["clipboard", "phishing"]},
{"not": {"p": "severity", "op": "lte", "v": "medium"}}]},
{"p": "incident_id", "op": "not_null"}
],
"limit": 5}4.4 Operators
Which operators a field accepts is listed with the field in 4.7 (and in the catalog).
| Operator | Value | True when the field is… | Example |
|---|---|---|---|
eq | one value | equal to | {"p": "status", "op": "eq", "v": "open"} |
neq | one value | not equal to (also true when the field is empty) | {"p": "action", "op": "neq", "v": "detected"} |
lt | one value | less than | {"p": "risk_score", "op": "lt", "v": 50} |
lte | one value | less than or equal to; on severity it follows the order info < low < medium < high < critical | {"p": "severity", "op": "lte", "v": "medium"} |
gt | one value | greater than | {"p": "id", "op": "gt", "v": 1200} |
gte | one value | greater than or equal to; on severity it follows the order info < low < medium < high < critical | {"p": "severity", "op": "gte", "v": "high"} |
between | [from, to] | between two values, both included | {"p": "event_time", "op": "between", "v": ["2026-11-01T00:00:00Z", "2026-11-02T00:00:00Z"]} |
in | a list of 1 to 500 values | equal to one of the values | {"p": "event_type", "op": "in", "v": ["clipboard", "phishing"]} |
not_in | a list of 1 to 500 values | none of the values (also true when the field is empty) | {"p": "status", "op": "not_in", "v": ["resolved", "false_positive"]} |
contains | text | contains the text (not case sensitive) | {"p": "url", "op": "contains", "v": "login"} |
starts_with | text | starts with the text | {"p": "url", "op": "starts_with", "v": "https://"} |
ends_with | text | ends with the text; on a domain field it also matches the domain itself, so example.com finds example.com and www.example.com | {"p": "site", "op": "ends_with", "v": "example.com"} |
has_item | one item | a list field (for example the rules of an event) contains the item | {"p": "rules_csv", "op": "has_item", "v": "ps_iex_irm"} |
is_null | no value | the field has no value | {"p": "incident_id", "op": "is_null"} |
not_null | no value | the field has a value | {"p": "incident_id", "op": "not_null"} |
is_empty | no value | the field has no value or an empty text | {"p": "source", "op": "is_empty"} |
not_empty | no value | the field has a non-empty text | {"p": "source", "op": "not_empty"} |
last | {"n": number, "unit": "second", "minute", "hour" or "day"} | within the last period (up to 10 years) | {"p": "event_time", "op": "last", "v": {"n": 7, "unit": "day"}} |
4.5 Reading more than one page
When more rows exist than fit in one answer, next_cursor is a string. Send the same query again with "cursor": "<next_cursor>" and you get the next page; stop when next_cursor is null (recipe 3.1 does exactly this). A cursor belongs to its query: if you change anything else in the query, the console refuses the cursor (bad_cursor) and you start again without one. Rows are never skipped or repeated between pages.
truncated: true means the console cut an answer at its size limit before limit rows; continue with next_cursor as usual.
4.6 Limits and errors
Limits keep one integration from slowing the console down for everyone. When you reach one, the answer says how long to wait.
| Limit | Value |
|---|---|
| Rows per answer | up to 1000 (default 100); continue with next_cursor |
| Data per answer | 2 MB (truncated: true when an answer was cut; at least one row is always returned) |
| Request body | 256 KB |
| Query size | 64 conditions, 4 levels of any / all / not, 60 columns, 500 values in one in list, 5 counts of related objects |
| Queries per minute, per key | as set on the key (default 120, at most 600) |
| Requests per day, per key | as set on the key (at most 1,000,000) |
| Catalog calls per minute, per key | 60 |
| All keys of your organization together | 600 requests per minute |
| Requests per minute from one IP address | 1200 (queries), 600 (catalog) |
| Refused authentications from one IP address | 20 per 10 minutes (protects against guessing keys) |
| Active keys per organization | 20 |
| Query time | a query that runs too long is stopped (query_timeout) |
Every error answer has the same shape — ok is false, error names the problem, message (most errors) explains it in words:
{"ok": false, "error": "invalid_query", "reason": "bad_operator", "message": "Operator contains is not allowed for Severity."}| HTTP | error | What happened | What to do |
|---|---|---|---|
| 400 | empty_body | a POST without a body | send the query as a JSON object |
| 400 | invalid_json | the body is not a JSON object | send one JSON object |
| 400 | invalid_query | the query cannot be run; "reason" and "message" say why (reasons below) | fix the query |
| 401 | api_key_expired | the key passed its expiry date | create a new key, or ask an administrator to change the date |
| 401 | api_key_owner_disabled | the person who created the key was disabled, so the key was revoked | an administrator creates a new key |
| 401 | api_key_revoked | the key was revoked | create a new key |
| 401 | device_token_not_accepted | a browser extension credential was sent instead of an API key | use an API key (ngk_…) |
| 401 | missing_or_malformed_key | no key, or not in the form ngk_ + 48 characters | send Authorization: Bearer <key> |
| 401 | unknown_api_key | the key does not exist | check that you copied the whole key |
| 403 | feature_not_available | the Read API, or this data type, is not part of your plan | contact your provider |
| 403 | forbidden | the key's role or data types do not allow this type or field | use a key with the needed role and data types |
| 403 | https_required | the request used plain HTTP and this console accepts only HTTPS | use https:// |
| 403 | ip_not_allowed | the request comes from an address that is not in the key's allow-list | call from an allowed address, or update the list |
| 403 | tenant_suspended | your organization's console is suspended | contact your provider |
| 404 | not_found | no object with this id in your organization | check the id |
| 404 | unknown_type | the data type does not exist | GET catalog.php lists the types your key can read |
| 405 | method_not_allowed | wrong HTTP method | GET for the catalog and single objects, POST for queries |
| 413 | payload_too_large | the body is over the size limit | make the query smaller |
| 429 | rate_limited | too many requests; "scope" says which limit and "retry_after_sec" how long to wait | wait retry_after_sec seconds, then continue |
| 500 | server_error | an error on the console | try again later; if it persists, tell your provider |
| 503 | not_installed | the console is not installed yet | contact your provider |
| 503 | query_timeout | the query took too long | add a time filter, ask for fewer rows or use core.event_summary |
rate_limited answers also carry scope (which limit) and retry_after_sec. The scopes:
scope | The limit reached |
|---|---|
ip | requests from one IP address |
ip_refused | refused authentications from one IP address |
key | this key's requests per minute |
key_daily | this key's requests per day |
tenant | all keys of your organization together |
invalid_query answers carry a reason:
reason | Meaning |
|---|---|
bad_aggregate | a calculation this field does not offer |
bad_alias | a name given with "as" that is not valid or is used twice |
bad_columns | no columns, too many, or a combination that needs group (plain fields together with calculations) |
bad_cursor | a cursor that does not belong to this query |
bad_filter | a condition that cannot be used (for example on a field that cannot be filtered) |
bad_group | a field that cannot be grouped |
bad_limit | a limit outside 1 to the maximum |
bad_operator | an operator this field does not accept (see its operators in 4.7) |
bad_paging | more than one of cursor, page and offset; an offset below 0 or a page below 1; or paging past its upper bound |
bad_property | a field name that does not exist for this type |
bad_request | a GET without both type and id |
bad_sort | a sort on a field that cannot be sorted |
bad_spec | a value of the wrong kind somewhere in the query |
bad_value | a value that does not fit the field or the operator |
needs_time_filter | the query reads the raw payload of events (a sensitive field): add a time filter, for example the last 7 days |
too_complex | too many conditions, nesting levels or values |
unknown_field | a field in the request that the API does not know (allowed: type, columns, filters, search, group, sort, limit, offset, page, cursor) |
4.7 Every data type and every field
For each data type: what it holds, what it needs, its key and time fields, the fields the free-text search looks in, the fields you get without columns, the related objects (use them as "relation.field", for example "device.label") and then every field. In the field tables: Ops = the operators the field accepts (empty = it cannot be filtered); Sort / Group = it can be sorted / grouped (time = grouped by hour, day, week or month); Calc = the calculations it offers.
core.event — Threat Events
Threat events reported by your browsers. The time field is event_time.
- Available with: every plan with the Read API; at most 1000 rows per answer.
- Key field:
id; time field:event_time searchlooks in:event_id,hostname,site,url,rules_csv,evidence_sha256- Without
columns:event_time,severity,event_type,site,device.label,action,blocked - Related objects:
device→core.device(one),incident→core.incident(one),rules→core.event_rule(many: count them or filter with exists)
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
event_id | Event ID | text | eq, in | yes | |||
event_type | Type | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | count, count_distinct | the event types below |
is_telemetry | Telemetry | bool | eq | yes | yes | sum | |
event_time | Time | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
received_at | Received | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
action_authoritative | Action authoritative | bool | eq | yes | yes | sum | |
document_id | Document ID | text | eq, in | yes | |||
frame_id | Frame ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
frame_url | Frame URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
enforcement_reason | Enforcement reason | text | contains, is_null, not_null | ||||
escalation | Severity raised by the console | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | ||||
user_reported_at | Reported by the user | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
command_hash | Command (SHA-256) | hash | eq, in, is_null, not_null | yes | yes | count_distinct | |
write_class | How the command reached the clipboard | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
notification_status | Notification status | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
notification_reason | Notification reason | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
evidence_source | Evidence source | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
evidence_hash_algorithm | Evidence hash algorithm | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
evidence_byte_length | Evidence bytes | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
page_entity_hash | Page entity hash | hash | eq, in, is_null, not_null | yes | yes | ||
severity | Severity | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | count | values: info, low, medium, high, critical |
severity_rank | Severity rank | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | min, max, sum | |
action | Action | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
blocked | Blocked | bool | eq | yes | yes | sum | |
would_block | Would block | bool | eq | yes | yes | sum | |
repeat_count | Repeats | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
last_repeat_at | Last repeat | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
url | URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
hostname | Host | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | count_distinct | |
site | Site | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | count_distinct | |
top_level_url | Top-level URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
target_url | Target URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
source | Source | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
source_trust | Source trust | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
signal_strength | Signal strength | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
confidence | Confidence | number | eq, neq, lt, lte, gt, gte, between, is_null, not_null | yes | avg, min, max | ||
score | Score | number | eq, neq, lt, lte, gt, gte, between, is_null, not_null | yes | avg, min, max, sum | ||
site_score | Site score | number | eq, neq, lt, lte, gt, gte, between, is_null, not_null | yes | avg, min, max | ||
enforcement | Enforcement | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
rules_csv | Rules | csv | has_item, contains, is_empty, not_empty | ||||
mitre_csv | MITRE ATT&CK | csv | has_item, contains, is_empty, not_empty | ||||
evidence_sha256 | Evidence SHA-256 | hash | eq, in, is_null, not_null | yes | yes | count_distinct | |
evidence_length | Evidence length | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
evidence_truncated | Evidence truncated | bool | eq | yes | yes | sum | |
evidence_text | Evidence | text | contains | sensitive: only an analyst key allowed to read sensitive data | |||
policy_id | Policy ID | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
correlation_id | Correlation ID | text | eq, in | yes | |||
ext_incident_id | Extension incident ID | text | eq, in | yes | |||
incident_id | Incident | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | count_distinct | |
device_id | Device | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | count_distinct | |
browser_session_id | Browser session | text | eq, in | yes | |||
artifact_type | Artifact type | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
artifact_hash | Artifact hash | hash | eq, in, is_null, not_null | yes | yes | ||
resource_count | Resource count | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
extension_version | Extension version | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
payload_json | Raw payload | text | contains | sensitive: only an analyst key allowed to read sensitive data; only together with a time filter | |||
lure_url | Lure URL | url | eq, contains | only together with a time filter |
core.event_rule — Rule Matches
Which detection rule matched which event: one row per event and rule.
- Available with: every plan with the Read API; at most 1000 rows per answer.
- Key field:
event_pk; time field:event_time searchlooks in: nothing (free-text search is not available)- Without
columns: every field - Related objects:
event→core.event(one)
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
event_pk | Event | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
rule_id | Rule | text | eq, in, starts_with, contains | yes | yes | count, count_distinct | |
event_time | Time | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.device — Devices
Your enrolled browsers.
- Available with: every plan with the Read API; at most 1000 rows per answer.
- Key field:
id; no time field searchlooks in:label,hostname,installation_id- Without
columns:label,status,extension_version,last_seen_at - Related objects:
incidents→core.incident(many: count them or filter with exists),events→core.event(many: count them or filter with exists)
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
installation_id | Installation ID | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
label | Label | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
hostname | Hostname | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
platform | Platform | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
browser | Browser | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
extension_version | Extension version | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | count_distinct | |
status | Status | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | values: active, disabled, revoked | |
cloud_state | Cloud state | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
license_state | Licence state (reported) | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
ent_seq_reported | Entitlement # (reported) | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
license_reported_at | Licence reported | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
queue_length | Queue | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
event_count | Events | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
last_event_at | Last event | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_ip | Last IP | ip | eq, in, starts_with | yes | |||
created_at | Enrolled | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.incident — Incidents
Incidents: the threat events of one browser on one site within 30 minutes, grouped as one attack.
- Available with: every plan with the Read API; at most 1000 rows per answer.
- Key field:
id; time field:last_seen_at searchlooks in:site,title- Without
columns: every field - Related objects:
device→core.device(one),assignee→core.user(one),events→core.event(many: count them or filter with exists)
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
device_id | Device | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | ||
site | Site | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | count_distinct | |
title | Title | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
status | Status | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | values: open, investigating, resolved, false_positive | |
severity | Severity | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | count | values: info, low, medium, high, critical |
severity_rank | Severity rank | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | min, max, sum | |
risk_score | Risk | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
event_count | Events | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
types_csv | Event types | csv | has_item, contains, is_empty, not_empty | ||||
rules_csv | Rules | csv | has_item, contains, is_empty, not_empty | ||||
mitre_csv | MITRE ATT&CK | csv | has_item, contains, is_empty, not_empty | ||||
chain_verdict | Chain | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
blocked_count | Blocked | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
first_seen_at | First seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
assignee_user_id | Assignee | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | ||
ext_incident_ids | Extension incident IDs | text | contains | ||||
notes | Notes | text | contains | ||||
updated_at | Updated | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
resolved_at | Resolved | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
created_at | Created | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.user — Users
The people of your console (names only, for the assignee of incidents).
- Available with: every plan with the Read API; at most 1000 rows per answer.
- Key field:
id; no time field searchlooks in: nothing (free-text search is not available)- Without
columns: every field - Related objects: none
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
username | Username | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
display_name | Name | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes |
core.domain — Intelligence — Domains
Intelligence: every domain seen in your events or reported by your browsers, with its risk and verdict.
- Available with: the Intelligence feature; at most 1000 rows per answer.
- Key field:
id; time field:last_seen_at searchlooks in: nothing (free-text search is not available)- Without
columns: every field - Related objects: none
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
domain | Domain | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | ||
site | Site | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | ||
first_seen_at | First seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
threat_event_count | Threat events | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
telemetry_count | Telemetry | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
device_count | Devices | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
max_severity_rank | Max severity | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | min, max, sum | |
blocked_count | Blocked | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
types_csv | Event types | csv | has_item, contains, is_empty, not_empty | ||||
risk_score | Risk | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | sum, avg, min, max | |
ext_score | Sensor score | number | eq, neq, lt, lte, gt, gte, between, is_null, not_null | yes | avg, max | ||
ext_classification | Sensor classification | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
ext_label | Site label | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
ext_label_reason | Site label reason | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | ||||
ext_labels | Site labels | csv | has_item, contains, is_empty, not_empty | ||||
ext_label_source | Site label set by | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
ext_label_note | Site evidence note | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | ||||
ext_updated_at | Sensor update | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
ext_signals_json | Sensor signals | text | contains | ||||
ext_contract_keys | Sensor contract keys | text | contains | ||||
verdict_by | Verdict by | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
verdict | Verdict | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | values: malicious, suspicious, benign, unknown | |
verdict_note | Verdict note | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
verdict_at | Verdict time | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.artifact — Artifacts
Files and scripts seen (by hash).
- Available with: the Artifacts feature; at most 1000 rows per answer.
- Key field:
id; time field:last_seen_at searchlooks in: nothing (free-text search is not available)- Without
columns: every field - Related objects:
sample→core.event(one)
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
sha256 | SHA-256 | hash | eq, in, is_null, not_null | yes | |||
kind | Kind | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
first_seen_at | First seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
event_count | Events | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
device_count | Devices | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
site_count | Sites | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
types_csv | Event types | csv | has_item, contains, is_empty, not_empty | ||||
sample_event_pk | Sample event | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
verdict | Verdict | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes |
core.command — Commands
Commands that pages tried to put on the clipboard (by hash), with what they would have done.
- Available with: every plan with the Read API; at most 1000 rows per answer.
- Key field:
id; time field:last_seen_at searchlooks in:cmd_hash,template_hash,payload_hosts- Without
columns:last_seen_at,interpreter,write_class,events,detected_only,cmd_hash - Related objects: none
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
cmd_hash | Command SHA-256 | hash | eq, in, is_null, not_null | yes | yes | ||
template_hash | Template SHA-256 | hash | eq, in, is_null, not_null | yes | yes | count_distinct | |
template_text | Template | text | eq, contains | ||||
interpreter | Interpreter | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
write_class | How it reached the clipboard | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
command_text | Command | text | contains | sensitive: only an analyst key allowed to read sensitive data | |||
decoded_text | Decoded command | text | contains | sensitive: only an analyst key allowed to read sensitive data | |||
payload_hosts | Download hosts | csv | has_item, contains, is_empty, not_empty | ||||
rules_csv | Rules | csv | has_item, contains, is_empty, not_empty | ||||
events | Events | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
blocked | Blocked | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
replaced | Clipboard cleaned | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
detected_only | Could have run | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
first_seen_at | First seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.resource — Resource Lineage
Resource lineage: which page loaded which resource.
- Available with: the Resource Lineage feature; at most 1000 rows per answer.
- Key field:
id; time field:last_seen_at searchlooks in:resource_site,page_site,resource_url- Without
columns: every field - Related objects: none
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
identity_hash | Identity hash | hash | eq, in, is_null, not_null | yes | |||
resource_url | Resource URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
resource_host | Resource host | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | ||
resource_site | Resource site | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | count_distinct | |
resource_type | Resource type | text | eq, in, neq | yes | yes | ||
page_site | Page site | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | count_distinct | |
third_party | Third party | bool | eq | yes | yes | sum | |
observations | Observations | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
first_seen_at | First seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.rpc_endpoint — Web3 — RPC Endpoints
Web3: the blockchain RPC endpoints pages talked to.
- Available with: the Web3 feature; at most 1000 rows per answer.
- Key field:
id; time field:last_seen_at searchlooks in:endpoint_host,provider,sites_csv- Without
columns: every field - Related objects: none
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
endpoint_host | Endpoint | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | ||
provider | Provider | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
chain | Chain | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
methods_csv | Methods | csv | has_item, contains, is_empty, not_empty | ||||
sites_csv | Sites | csv | has_item, contains, is_empty, not_empty | ||||
intents_csv | Intents | csv | has_item, contains, is_empty, not_empty | ||||
event_count | Events | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
block_count | Blocks | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
max_severity_rank | Max severity | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | min, max, sum | |
first_seen_at | First seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.web3_contract — Web3 — Contracts
Web3: smart contracts pages read or called.
- Available with: the Web3 feature; at most 1000 rows per answer.
- Key field:
id; time field:last_seen_at searchlooks in:address,contract_key,contract_name,websites_json- Without
columns: every field - Related objects: none
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
contract_key | Contract key | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
chain_id | Chain ID | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
chain | Chain | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
address | Address | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
contract_name | Name | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
verified | Verified | bool | eq | yes | yes | sum | |
status | Status | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
verdict_status | Verdict | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
verdict_severity | Verdict severity | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | values: info, low, medium, high, critical | |
verdict_reason | Verdict reason | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
reputation_status | Reputation | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
observations | Observations | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
last_method | Last method | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
last_intent | Last intent | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
last_intent_risk | Last intent risk | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
websites_json | Websites | text | contains | ||||
providers_json | Providers | text | contains | ||||
selectors_json | Selectors | text | contains | ||||
raw_json | Sensor record | text | contains | ||||
abi_functions | ABI functions | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
device_count | Devices | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
first_seen_at | First seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
updated_at | Updated | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.web3_contract_device — Web3 — Contract sightings
Web3: which browser met which contract.
- Available with: the Web3 feature; at most 1000 rows per answer.
- Key field:
contract_id; time field:last_seen_at searchlooks in: nothing (free-text search is not available)- Without
columns: every field - Related objects:
device→core.device(one),contract→core.web3_contract(one)
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
contract_id | Contract | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
device_id | Device | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | count_distinct | |
last_seen_at | Last seen | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max |
core.audit — Audit Log
The audit log. Not available through the API (it is for administrators).
core.telemetry — Telemetry
Telemetry records (only when your organization collects telemetry); same fields as threat events.
- Available with: every plan with the Read API; at most 1000 rows per answer.
- Key field:
id; time field:event_time searchlooks in:event_id,hostname,site,url,rules_csv,evidence_sha256- Without
columns:event_time,event_type,site,device.label,resource_count - Related objects:
device→core.device(one)
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
id | ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
event_id | Event ID | text | eq, in | yes | |||
event_type | Type | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | count, count_distinct | the event types below |
is_telemetry | Telemetry | bool | eq | yes | yes | sum | |
event_time | Time | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
received_at | Received | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
action_authoritative | Action authoritative | bool | eq | yes | yes | sum | |
document_id | Document ID | text | eq, in | yes | |||
frame_id | Frame ID | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | |||
frame_url | Frame URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
enforcement_reason | Enforcement reason | text | contains, is_null, not_null | ||||
escalation | Severity raised by the console | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | ||||
user_reported_at | Reported by the user | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
command_hash | Command (SHA-256) | hash | eq, in, is_null, not_null | yes | yes | count_distinct | |
write_class | How the command reached the clipboard | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
notification_status | Notification status | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
notification_reason | Notification reason | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
evidence_source | Evidence source | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
evidence_hash_algorithm | Evidence hash algorithm | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
evidence_byte_length | Evidence bytes | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
page_entity_hash | Page entity hash | hash | eq, in, is_null, not_null | yes | yes | ||
severity | Severity | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | count | values: info, low, medium, high, critical |
severity_rank | Severity rank | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | min, max, sum | |
action | Action | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
blocked | Blocked | bool | eq | yes | yes | sum | |
would_block | Would block | bool | eq | yes | yes | sum | |
repeat_count | Repeats | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
last_repeat_at | Last repeat | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
url | URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
hostname | Host | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | count_distinct | |
site | Site | domain | eq, neq, in, not_in, ends_with, contains, is_null, not_null, is_empty, not_empty | yes | yes | count_distinct | |
top_level_url | Top-level URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
target_url | Target URL | url | eq, contains, starts_with, is_null, not_null, is_empty, not_empty | ||||
source | Source | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
source_trust | Source trust | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
signal_strength | Signal strength | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
confidence | Confidence | number | eq, neq, lt, lte, gt, gte, between, is_null, not_null | yes | avg, min, max | ||
score | Score | number | eq, neq, lt, lte, gt, gte, between, is_null, not_null | yes | avg, min, max, sum | ||
site_score | Site score | number | eq, neq, lt, lte, gt, gte, between, is_null, not_null | yes | avg, min, max | ||
enforcement | Enforcement | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
rules_csv | Rules | csv | has_item, contains, is_empty, not_empty | ||||
mitre_csv | MITRE ATT&CK | csv | has_item, contains, is_empty, not_empty | ||||
evidence_sha256 | Evidence SHA-256 | hash | eq, in, is_null, not_null | yes | yes | count_distinct | |
evidence_length | Evidence length | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
evidence_truncated | Evidence truncated | bool | eq | yes | yes | sum | |
evidence_text | Evidence | text | contains | sensitive: only an analyst key allowed to read sensitive data | |||
policy_id | Policy ID | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | |||
correlation_id | Correlation ID | text | eq, in | yes | |||
ext_incident_id | Extension incident ID | text | eq, in | yes | |||
incident_id | Incident | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | count_distinct | |
device_id | Device | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | count_distinct | |
browser_session_id | Browser session | text | eq, in | yes | |||
artifact_type | Artifact type | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
artifact_hash | Artifact hash | hash | eq, in, is_null, not_null | yes | yes | ||
resource_count | Resource count | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, avg, min, max | ||
extension_version | Extension version | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
payload_json | Raw payload | text | contains | sensitive: only an analyst key allowed to read sensitive data; only together with a time filter | |||
lure_url | Lure URL | url | eq, contains | only together with a time filter |
core.event_summary — Event summary (hourly)
Hourly counts of threat events: fast for long time ranges.
- Available with: every plan with the Read API; at most 1000 rows per answer.
- Key field:
hour; time field:hour searchlooks in: nothing (free-text search is not available)- Without
columns:hour,event_type,severity,action,n - Related objects: none
| Field | Label | Type | Ops | Sort | Group | Calc | Notes |
|---|---|---|---|---|---|---|---|
hour | Hour | datetime | between, gt, gte, lt, lte, last, is_null, not_null | yes | time | min, max | |
event_type | Type | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | count_distinct | the event types below |
severity | Severity | enum | eq, neq, in, not_in, gte, lte, is_null, not_null | yes | yes | values: info, low, medium, high, critical | |
severity_rank | Severity rank | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | yes | min, max | |
action | Action | text | eq, neq, in, not_in, contains, starts_with, ends_with, is_null, not_null, is_empty, not_empty | yes | yes | ||
blocked | Blocked | bool | eq | yes | yes | ||
n | Events | integer | eq, neq, lt, lte, gt, gte, between, in, not_in, is_null, not_null | yes | sum, max |
Event types
The values of event_type (threat events and telemetry):
event_type | In the console | Group |
|---|---|---|
clipboard | Clipboard Write | ClickFix / Clipboard |
clipboard_policy | Clipboard Policy Block | ClickFix / Clipboard |
dom | ClickFix Page Scan | ClickFix / Clipboard |
inline_script | Inline Script | Script / Payload |
third_party_domain | 3rd-Party New Domain | Infrastructure |
domain_age | Newly Registered Domain | Infrastructure |
device_code | Device Code Phishing | Identity / Phishing |
rpc_response_observed | RPC Response Observed | Web3 / RPC |
rpc_etherhiding | EtherHiding (contract-hosted lure) | Web3 / RPC |
script_loader | Script Loader (decrypt / EtherHiding) | Web3 / RPC |
rpc_behavior_detected | RPC Behavior Detected | Web3 / RPC |
rpc_behavior_block | RPC Behavior Block | Web3 / RPC |
rpc_block | Blockchain RPC Block | Web3 / RPC |
rpc_enforcement_rule | RPC Enforcement Rule | Web3 / RPC |
phishing | Phishing — Password Field | Identity / Phishing |
phishing_precaution | Credential Risk — New Domain | Identity / Phishing |
service_worker | Service Worker | Browser Persistence |
blob_phishing | Blob Phishing | Identity / Phishing |
browser_in_browser | Browser-in-the-Browser | Identity / Phishing |
ioc_match | Threat Indicator Match | Infrastructure |
hidden_iframe | Hidden Iframe from a Third-Party Frame | Browser Behavior |
wallet_request | Wallet Signature Request | Web3 |
webrtc | WebRTC Behavioral Signal | Browser Behavior |
correlation | Temporal Correlation | Correlation |
site_tech_observation | Site Technology (telemetry) | Telemetry |
resource_observation_batch | Resource Observation (telemetry) | Telemetry |
A newer browser extension may report a type that is not in this list yet; the API returns it as it is.
4.8 What the SIEM receives
Up to 5 destinations per organization. Every minute the console sends the new threat events in batches of up to 100, oldest first (events younger than 15 seconds wait for the next minute). It moves on only after a 2xx answer; after an error it tries again later, waiting longer each time and respecting a Retry-After header. It sends only to HTTPS addresses on the public internet, does not follow redirects and connects to the address it checked. The evidence itself (for example the command a page tried to copy) is never sent, only its SHA-256.
Formats:
json— JSON batch (generic webhook, Elastic, Logic Apps)splunk_hec— Splunk HTTP Event Collectorcef— CEF lines (text/plain)
Every event becomes one record with these fields:
| Field | Meaning |
|---|---|
vendor | always "ByteMantle" |
product | always "ByteMantle Console" |
console_version | the version of the console that sent it |
tenant_id | your organization's number |
tenant | your organization's name |
id | the event's number in the console (the id of the Read API) |
event_id | the event's unique identifier, the same in the browser and in the console; use it to recognise repeats |
type | the kind of event (4.7, event types) |
telemetry | true for a telemetry record, false for a threat event |
time | when the browser saw it (UTC, ISO 8601) |
received | when the console received it |
severity | info, low, medium, high or critical |
action | what the extension did (detected, blocked, warned, neutralized, prevented) |
blocked | true when the extension blocked it |
url | the address of the page |
host | the host name of the page |
site | the registrable domain of the page |
source | which detector reported it |
confidence | the detector's confidence, 0 to 1, or null |
score | the detector's score, or null |
rules | the detection rules that matched |
mitre | the MITRE ATT&CK techniques |
evidence_sha256 | the SHA-256 of the evidence (the evidence itself is never sent), or null |
incident_id | the number of the incident it belongs to, or null |
correlation_id | the correlation identifier of the extension, or null |
device | the browser: id, hostname (when known), label and extension_version |
A JSON batch, exactly as a console sent it:
{
"source": "nextgen-console",
"count": 2,
"events": [
{
"vendor": "ByteMantle",
"product": "ByteMantle Console",
"console_version": "2.14.1",
"tenant_id": "1",
"tenant": "Contoso",
"id": "241328",
"event_id": "ngav-1793709842735-4hdr7nlf",
"type": "correlation",
"telemetry": false,
"time": "2026-11-03T12:44:02+00:00",
"received": "2026-11-03T12:44:02+00:00",
"severity": "high",
"action": "detected",
"blocked": false,
"url": "http://lure2.swu-zz.com:18766/",
"host": "lure2.swu-zz.com",
"site": "swu-zz.com",
"source": "temporal_correlation",
"confidence": 0.8,
"score": null,
"rules": [
"sw_on_flagged_site_chain"
],
"mitre": [
"T1189",
"T1204.004"
],
"evidence_sha256": null,
"incident_id": "382",
"correlation_id": null,
"device": {
"id": "245",
"hostname": null,
"label": "Linux · Chrome · #0023",
"extension_version": "3.12.4"
}
},
{
"vendor": "ByteMantle",
"product": "ByteMantle Console",
"console_version": "2.14.1",
"tenant_id": "1",
"tenant": "Contoso",
"id": "241327",
"event_id": "ngav-1793709842731-ptspuqj0",
"type": "service_worker",
"telemetry": false,
"time": "2026-11-03T12:44:02+00:00",
"received": "2026-11-03T12:44:02+00:00",
"severity": "info",
"action": "remediated",
"blocked": false,
"url": "http://lure2.swu-zz.com:18766/",
"host": "lure2.swu-zz.com",
"site": "swu-zz.com",
"source": "service_worker",
"confidence": null,
"score": null,
"rules": [
"sw.unload.auto"
],
"mitre": [],
"evidence_sha256": null,
"incident_id": "382",
"correlation_id": null,
"device": {
"id": "245",
"hostname": null,
"label": "Linux · Chrome · #0023",
"extension_version": "3.12.4"
}
}
]
}Splunk HEC: one line per event, each a JSON object with time (Unix seconds), host (the browser), source, sourcetype (nextgen:event) and event (the record above):
{"time":1793709842,"host":"Linux · Chrome · #0023","source":"nextgen-console","sourcetype":"nextgen:event","event":{"vendor":"ByteMantle","product":"ByteMantle Console","console_version":"2.14.1","tenant_id":"1","tenant":"Contoso","id":"241328","event_id":"ngav-1793709842735-4hdr7nlf","type":"correlation","telemetry":false,"time":"2026-11-03T12:44:02+00:00","received":"2026-11-03T12:44:02+00:00","severity":"high","action":"detected","blocked":false,"url":"http://lure2.swu-zz.com:18766/","host":"lure2.swu-zz.com","site":"swu-zz.com","source":"temporal_correlation","confidence":0.8,"score":null,"rules":["sw_on_flagged_site_chain"],"mitre":["T1189","T1204.004"],"evidence_sha256":null,"incident_id":"382","correlation_id":null,"device":{"id":"245","hostname":null,"label":"Linux · Chrome · #0023","extension_version":"3.12.4"}}}
{"time":1793709842,"host":"Linux · Chrome · #0023","source":"nextgen-console","sourcetype":"nextgen:event","event":{"vendor":"ByteMantle","product":"ByteMantle Console","console_version":"2.14.1","tenant_id":"1","tenant":"Contoso","id":"241327","event_id":"ngav-1793709842731-ptspuqj0","type":"service_worker","telemetry":false,"time":"2026-11-03T12:44:02+00:00","received":"2026-11-03T12:44:02+00:00","severity":"info","action":"remediated","blocked":false,"url":"http://lure2.swu-zz.com:18766/","host":"lure2.swu-zz.com","site":"swu-zz.com","source":"service_worker","confidence":null,"score":null,"rules":["sw.unload.auto"],"mitre":[],"evidence_sha256":null,"incident_id":"382","correlation_id":null,"device":{"id":"245","hostname":null,"label":"Linux · Chrome · #0023","extension_version":"3.12.4"}}}CEF: one line per event (severity: info 1, low 3, medium 5, high 8, critical 10):
CEF:0|ByteMantle|ByteMantle|2.14.1|correlation|correlation on swu-zz.com|8|rt=1793709842000 request=http://lure2.swu-zz.com:18766/ dhost=lure2.swu-zz.com shost=Linux · Chrome · #0023 act=detected externalId=ngav-1793709842735-4hdr7nlf cs1Label=tenant cs1=Contoso cs2Label=rules cs2=sw_on_flagged_site_chain cs3Label=mitre cs3=T1189,T1204.004
CEF:0|ByteMantle|ByteMantle|2.14.1|service_worker|service_worker on swu-zz.com|1|rt=1793709842000 request=http://lure2.swu-zz.com:18766/ dhost=lure2.swu-zz.com shost=Linux · Chrome · #0023 act=remediated externalId=ngav-1793709842731-ptspuqj0 cs1Label=tenant cs1=Contoso cs2Label=rules cs2=sw.unload.auto cs3Label=mitre5. Versions and changes
This is version 1 of the Read API (/api/v1/). New data types, fields and error codes may be added in later console versions; existing ones keep their name and meaning within version 1. Your console's catalog always describes what your version offers. The changes of each console version are in its release notes.