Other Commands
The star of the FSQL show is the QUERY command. But FSQL has a supporting cast of other commands. The EXPLAIN commands allow users to interrogate the schema, inspect what's actually mapped across their connected data, list their connections, detections, and entities, or review FSQL documentation, and the VALIDATE QUERY command checks the validity of an FSQL query.
Note: if you're using FSQL through Query's search UI, you only have access to the QUERY command today. API and console users have access to the full set of commands shown here.
FSQL also has a family of access-control statements — GRANT, REVOKE, EXPLAIN GRANTS, and EXPLAIN GROUPS — for managing which groups and users can use or edit your connectors and detections, plus a group-management family — CREATE GROUP, RENAME GROUP, DROP GROUP, ADD USER, REMOVE USER, and EXPLAIN MEMBERS OF — for creating and populating the groups themselves. Those are covered separately in Permission Commands.
EXPLAIN VERSION
FSQL is new technology and advancing quickly. The EXPLAIN VERSION command can retrieve the FSQL and Query Data Model versions of the FSQL server you're working with.
EXPLAIN VERSIONResponse:
{
"fsql": "fsql-0.5.0",
"qdm": "qdm-1.4.1+ocsf-1.4.0"
}EXPLAIN ATTRIBUTES
FSQL owes a lot of its power to its attribute selectors. If you'd like to test an attribute selector, you can see what one evaluates to with the EXPLAIN ATTRIBUTES command. EXPLAIN FIELDS is an accepted alias.
EXPLAIN [MASKED|UNMASKED] ATTRIBUTES <attribute-selector>The optional MASKED / UNMASKED modifier narrows the result to the selected attributes that are hidden from you, or visible to you, under your column-masking rules.
For example, if you want to see all fields of network_activity that are IP observables, try the following:
EXPLAIN ATTRIBUTES network_activity.%ipResponse:
[
"network_activity.device.ip",
"network_activity.device.network_interfaces.ip",
"network_activity.dst_endpoint.intermediate_ips",
"network_activity.dst_endpoint.ip",
"network_activity.dst_endpoint.ip_intelligence.ip",
"network_activity.dst_endpoint.proxy_endpoint.intermediate_ips",
"network_activity.dst_endpoint.proxy_endpoint.ip",
"network_activity.load_balancer.dst_endpoint.intermediate_ips",
"network_activity.load_balancer.dst_endpoint.ip",
"network_activity.load_balancer.ip",
"network_activity.osint.email.x_originating_ip",
"network_activity.proxy.intermediate_ips",
"network_activity.proxy.ip",
"network_activity.proxy.ip_intelligence.ip",
"network_activity.proxy_endpoint.intermediate_ips",
"network_activity.proxy_endpoint.ip",
"network_activity.proxy_endpoint.ip_intelligence.ip",
"network_activity.proxy_http_request.x_forwarded_for",
"network_activity.src_endpoint.intermediate_ips",
"network_activity.src_endpoint.ip",
"network_activity.src_endpoint.ip_intelligence.ip",
"network_activity.src_endpoint.proxy_endpoint.intermediate_ips",
"network_activity.src_endpoint.proxy_endpoint.ip"
]EXPLAIN SCHEMA
The EXPLAIN SCHEMA command describes the schema for a given attribute selection. It expands the attribute selector expression and responds with the schema definition for each path that's been selected. If you're familiar with OCSF schema definitions, you should feel right at home with the output.
EXPLAIN SCHEMA network_activity.proxy.%ipResponse:
{
"network_activity.proxy.intermediate_ips": {
"caption": "Intermediate IP Addresses",
"type": "ip_t",
"requirement": "optional",
"description": "The intermediate IP Addresses. For example, the IP addresses in the HTTP X-Forwarded-For header.",
"is_array": true,
"observable": 2
},
"network_activity.proxy.ip": {
"caption": "IP Address",
"type": "ip_t",
"requirement": "recommended",
"description": "The IP address of the endpoint, in either IPv4 or IPv6 format.",
"is_array": false,
"observable": 2
},
"network_activity.proxy.ip_intelligence.ip": {
"caption": "IP Address",
"type": "ip_t",
"requirement": "optional",
"description": "The IP address, in either IPv4 or IPv6 format.",
"is_array": false,
"observable": 2
}
}By default, FSQL removes keys from the response with null values. You can enable them by adding WITH NULLS after the attribute selector (WITHOUT NULLS has the opposite effect). For example:
EXPLAIN SCHEMA network_activity.proxy.ip WITH NULLSResponse:
{
"network_activity.proxy.ip": {
"caption": "IP Address",
"type": "ip_t",
"requirement": "recommended",
"description": "The IP address of the endpoint, in either IPv4 or IPv6 format.",
"is_array": false,
"@deprecated": null,
"enum": null,
"group": null,
"observable": 2,
"profile": null,
"sibling": null,
"object_type": null,
"object_name": null,
"type_name": null
}
}EXPLAIN ENTITIES
The EXPLAIN ENTITIES command lists every entity FSQL knows about: the %-prefixed shortcuts like %ip and %username that expand to every field of a given observable type. Use it to discover the exact entity names available on the FSQL server you're working with.
EXPLAIN ENTITIESEach entity reports its aliases (the names you can write after %), a human-readable caption, a description, and the OCSF observable type_id it maps to.
Response:
{
"command": "EXPLAIN ENTITIES",
"entities": [
{
"aliases": ["ip_address", "ip"],
"caption": "IP Address",
"description": "Observable by Dictionary Type.Internet Protocol address (IP address), in either IPv4 or IPv6 format. For example:192.168.200.24, 2001:0db8:85a3:0000:0000:8a2e:0370:7334.",
"type_id": 2
},
{
"aliases": ["user_name", "username"],
"caption": "User Name",
"description": "Observable by Dictionary Type.User name. For example:john_doe.",
"type_id": 4
}
]
}EXPLAIN CONNECTORS
The EXPLAIN CONNECTORS command lists the connectors available in your Query tenant relevant to your FSQL session. By default it lists only active (enabled) connectors; add a status filter to see disabled connectors too.
The output includes the connector ID, connector name, the connector's alias, any tags applied to it, whether or not the connector is enabled, the name of the source platform, as well as OCSF events and objects supported by the Connector.
The alias and tags fields give you the stable references you can use in a FROM clause: the alias for a single connector, or a #-prefixed tag to query every connector that carries it. See Data Sources (FROM).
EXPLAIN [ACTIVE|ALL|DISABLED] CONNECTORS [<conns>]The status filter is optional:
ACTIVE(the default) lists only connectors that are enabled.DISABLEDlists only connectors that have been disabled.ALLlists every connector regardless of status.
EXPLAIN DISABLED CONNECTORS -- only connectors that are turned off
EXPLAIN ALL CONNECTORS #siem -- every connector tagged siem, enabled or notThe connector selection is also optional:
- With no selection,
EXPLAIN CONNECTORSlists every active connector available in your session. - Add
<conns>to limit the response to a subset of your connectors. It accepts any connector list you could use in aFROMclause — refer to connectors by numeric ID,#-prefixed tag, alias, or quoted display name, and separate multiple selections with commas to combine them. See Data Sources (FROM).
EXPLAIN CONNECTORS #siem, alienvaultResponse:
{
"command":"EXPLAIN CONNECTORS",
"connectors":[
{
"id":523,
"name":"AlienVault",
"alias":"alienvault",
"tags":[
"threat-intel"
],
"is_enabled":true,
"platform_name":"AlienVault",
"events":[
"osint_inventory_info"
],
"objects":[
"autonomous_system",
"digital_signature",
"dns_answer",
"location",
"metadata",
"observable",
"osint",
"product",
"reputation",
"threat_intelligence",
"unmapped"
]
},
{
"id":1011,
"name":"ATB - AzureActivity",
"alias":"atb-azureactivity",
"tags":[
"cloud",
"env/prod"
],
"is_enabled":true,
"platform_name":"AzureLogAnalytics",
"events":[
"api_activity"
],
"objects":[
"actor",
"api",
"group",
"network_endpoint",
"observable",
"resource_details",
"user"
]
}
]
}EXPLAIN DETECTIONS
The EXPLAIN DETECTIONS command lists the detections defined in your Query tenant. It's the discovery surface for finding the name or ID to use in a GRANT … ON DETECTION statement (see Permission Commands), and a quick way to review what each detection looks for.
EXPLAIN DETECTIONS [LIKE '<pattern>']The optional LIKE pattern is a glob (shell-style wildcards: * matches any run of characters, ? matches one), matched case-insensitively against the detection name. The quotes are required.
EXPLAIN DETECTIONS -- every detection in this tenant
EXPLAIN DETECTIONS LIKE 'brute*' -- detections whose name starts with "brute"Each detection reports its id and name, its severity and state (ACTIVE or PAUSED), a description, the fsql_query it runs, its custom_tags and mitre_tags, and its created_at and updated_at timestamps. Results are sorted by name.
Response:
{
"command": "EXPLAIN DETECTIONS",
"detections": [
{
"id": "42",
"name": "Brute force AD",
"is_active": true,
"custom_tags": ["soc"],
"mitre_tags": ["T1110"],
"severity": "HIGH",
"state": "ACTIVE",
"description": "Repeated failed logons against Active Directory",
"fsql_query": "QUERY authentication.* WITH authentication.status_id = FAILURE",
"created_at": "2026-01-01T00:00:00Z",
"updated_at": "2026-02-01T00:00:00Z"
}
]
}EXPLAIN CATALOG
Where EXPLAIN SCHEMA describes what the data model says an attribute could be, EXPLAIN CATALOG describes what your actual connected data does. It returns a computed view of your catalog: for each attribute that's mapped across your connections, it reports the attribute's scalar type and the invariants — the constraints that are known to hold on the values you can search. It's a machine-readable answer to the question "what can I usefully filter on across these connections?"
EXPLAIN CATALOG [<attribute-selector>] [FROM <connectors>]Both parts are optional:
- With no attribute selector,
EXPLAIN CATALOGreturns the whole catalog. Add an attribute selector (or a comma-separated list of them) to filter the response to just the attributes you care about. - Add a
FROMclause to compute the catalog over a subset of your connections. It accepts the same references as aQUERY'sFROMclause — a connector alias, a#-prefixed tag, a numeric connector ID, or a quoted display name. See Data Sources (FROM). With noFROMclause, the catalog spans all connections in your session.
Each entry reports a path, its type (for example ip, int, str, enum, or datetime), and its invariants. Common invariants include:
| Invariant | Meaning |
|---|---|
IsMapped | The attribute is populated, but no tighter constraint is known. |
EQ | Every record carries the same single value. |
OneOf | Values are drawn from a known, finite set. |
StartsWith / Matches | Values share a known prefix or match a known pattern. |
IfNotEmpty | When present, the value satisfies the nested invariant (it may also be absent). |
EXPLAIN CATALOG api_activity.* FROM #siemResponse:
{
"command": "EXPLAIN CATALOG",
"entries": [
{
"path": "api_activity.class_uid",
"type": "int",
"invariants": { "EQ": 6003 }
},
{
"path": "api_activity.count",
"type": "int",
"invariants": { "IfNotEmpty": { "OneOf": [0, 1, 2] } }
},
{
"path": "api_activity.message",
"type": "str",
"invariants": { "EQ": "m" }
},
{
"path": "api_activity.observables.type_id",
"type": "enum",
"invariants": { "OneOf": ["URL_STRING", "USER_NAME"] }
},
{
"path": "api_activity.observables.value",
"type": "str",
"invariants": { "IsMapped": null }
}
]
}Note: because the catalog is a union across the selected connections, invariants weaken as you widen the FROM clause. An attribute that always holds a single value in one connection (EQ) may relax to a set of values (OneOf) once a second connection is included, and an attribute mapped in only some connections may relax to a bare IsMapped. Narrowing the FROM clause to fewer connections tends to produce tighter invariants.
EXPLAIN MANUAL
The EXPLAIN MANUAL command responds with this documentation in Markdown format.
EXPLAIN MANUAL [FOR AI]Add FOR AI to receive a condensed version of the manual intended as context for an LLM or coding assistant. It contains the tutorial and the reference pages for attribute selectors, dates and times, and search filter operators, and omits the rest.
EXPLAIN QUERY
The EXPLAIN QUERY command shows how your FSQL query is converted into Query's internal search syntax. Invoke it with any search QUERY input to see how it will be interpreted by Query's engine. EXPLAIN SUMMARIZE works the same way for a SUMMARIZE command with analytics functions.
EXPLAIN [AST|EXPANDED] [WITH CONNECTOR IDS] QUERY <selector> [FROM <connectors>] [WITH <filter>] ...
EXPLAIN [AST|EXPANDED] SUMMARIZE <aggregation> <selector> ...ASTorEXPANDEDstates which of the two response elements you prefer to see. The console renders only the preferred one; the API response always includes both.WITH CONNECTOR IDSasks for the connectors in the expanded query'sFROMclause to be shown as connector IDs rather than the aliases, tags, or display names you typed. Current releases already resolveFROMreferences to connector IDs when expanding a query, so the flag rarely changes the output; it's accepted for compatibility with earlier versions and may also be written afterQUERY.
EXPLAIN EXPANDED WITH CONNECTOR IDS QUERY authentication.status_id FROM okta-logins, 'Active Directory'The response has two key elements.
expanded_query shows your FSQL query with all attribute selectors in the SHOW and WITH clauses expanded and any additional attributes or filters that were added by Query.
ast_query shows how your query will be translated into Query's internal hierarchical search syntax. The SHOW and WITH clauses are separate for each event type and list operations are explicitly assigned.
The values of these fields are meant to be human readable, and their formatting may change slightly.
EXPLAIN QUERY http_activity.* WITH %ip='136.103.57.67'Response:
{
"command": "explain ast query http_activity.* with %ip='136.103.57.67'",
"expanded_query": "QUERY\nSHOW\n http_activity.action_id,\n http_activity.activity_id,\n http_activity.app_name,\n http_activity.category_uid,\n http_activity.class_uid,\n http_activity.confidence_id,\n http_activity.confidence_score,\n http_activity.count,\n http_activity.disposition_id,\n http_activity.duration,\n http_activity.end_time,\n http_activity.http_status,\n http_activity.is_alert,\n http_activity.message,\n http_activity.record_id,\n http_activity.risk_details,\n http_activity.risk_level_id,\n http_activity.risk_score,\n http_activity.severity_id,\n http_activity.start_time,\n http_activity.status_code,\n http_activity.status_detail,\n http_activity.status_id,\n http_activity.time,\n http_activity.timezone_offset,\n http_activity.type_uid\nWITH ANY http_activity.observables.type_id EQ 'IP_ADDRESS'\n AND ANY http_activity.observables.value EQ '136.103.57.67'\n AND ANY http_activity.time GT '2025-06-27T04:07:44'\n AND ANY http_activity.time LE '2025-06-28T04:07:44'\nSINCE 2025-06-27T04:07:44\nUNTIL 2025-06-28T04:07:44\n",
"ast_query": "EVENT: http_activity\n WITH\n ANY observables { (type_id EQ 'IP_ADDRESS' AND value EQ '136.103.57.67') }\n AND time GT '2025-06-27T04:07:44'\n AND time LE '2025-06-28T04:07:44'\n SHOW\n action_id\n activity_id\n app_name\n category_uid\n class_uid\n confidence_id\n confidence_score\n count\n disposition_id\n duration\n end_time\n http_status\n is_alert\n message\n record_id\n risk_details\n risk_level_id\n risk_score\n severity_id\n start_time\n status_code\n status_detail\n status_id\n time\n timezone_offset\n type_uid\n"
}Below is an example from a terminal† with newlines rendered:
>>> EXPLAIN AST QUERY authentication.#primary WITH %ip='1.2.3.4'
EVENT: authentication
SHOW
auth_protocol_id
is_mfa
is_remote
logon_type_id
message
record_id
status_code
status_detail
status_id
WITH
ANY observables { (type_id EQ 'IP_ADDRESS' AND value EQ '1.2.3.4') }
AND time GT '2025-06-27T09:55:23'
AND time LE '2025-06-28T09:55:23'
† Terminal users may wish to useEXPLAIN AST QUERY or EXPLAIN EXPANDED QUERY to specify which format they prefer in the output.
VALIDATE QUERY
The VALIDATE QUERY command validates a FSQL query for debugging. VALIDATE SUMMARIZE works the same way, but validates a SUMMARIZE command with analytics functions.
VALIDATE QUERY #network.* WITH %ip = '10.0.0.1'Response:
{
"is_valid": true,
"input": "validate query #network.* with %ip = '10.0.0.1'"
}Updated 9 days ago