Skip to content
CLI
Skip navigation
CLI

Query

Run one read-only Cypher statement from the terminal, bind parameters with --param, and read the same JSON envelope the HTTP API returns.

Published

View as Markdown
On this page (4)

Query Documentation

whisper query sends one Cypher statement to WhisperGraph and prints the answer. It goes to the same endpoint the HTTP API documents and gets the same reply back. The CLI only saves the typing.

Sign in first. Then:

bash
whisper query "CALL whisper.identify(['api.openai.com'])"
text
host            vendor_id   canonical_name  is_canonical  confidence  category  roles                band     host_class
api.openai.com  cloudflare  Cloudflare      true          0.8         cdn       ["ORIGIN_AS","CDN"]  DERIVED  unknown
1 row(s)

Anything the Cypher chapter describes runs here: MATCH traversals, the procedures, CALL db.schema(). Writes are refused by the graph before they run, so there is nothing to be careful about.

Parameters

Never paste an indicator into the query string. Bind it with --param and refer to it as $name:

bash
whisper query 'CALL whisper.assess([$v])' --param v=8.8.8.8

The value is parsed as JSON when it parses (numbers, booleans, lists, objects) and taken as a string otherwise. 8.8.8.8 is not valid JSON, so it arrives as the string the procedure expects. A list works the same way:

bash
whisper query 'CALL whisper.assess($hosts)' --param 'hosts=["example.com","8.8.8.8"]'
text
host         label               band  coverage
example.com  benign-allowlisted  NONE  known-clean
8.8.8.8      benign-allowlisted  INFO  known-clean
2 row(s)

--param repeats, one per parameter.

JSON output

--json prints the reply exactly as the graph sent it: columns, rows and statistics.

bash
whisper query 'CALL whisper.assess([$v])' --param v=8.8.8.8 --json
json
{
  "columns": ["host", "label", "band", "sub_labels", "signals", "coverage", "evidence", "verdictScore", "isThreat", "threatSources"],
  "rows": [
    {
      "host": "8.8.8.8",
      "label": "benign-allowlisted",
      "band": "INFO",
      "coverage": "known-clean",
      "verdictScore": 0.0,
      "isThreat": false
    }
  ],
  "statistics": {"rowCount": 1, "executionTimeMs": 0}
}

That is the envelope from POST /api/query, so anything you already pipe API output into reads this too:

bash
whisper query 'CALL whisper.assess([$v])' --param v=8.8.8.8 --json | jq -r '.rows[0].band'

Read coverage before band. INFO on a known-clean address and NONE on an address nobody has ever looked at print the same colour in a terminal, and only one of them is reassuring. Coverage explains the difference.

When something goes wrong

Errors print as one line beginning whisper: and the command exits with status 1. A write is refused the same way:

bash
whisper query 'CREATE (n:X) RETURN n'
text
whisper: read_only

No key, a syntax error and an unreachable graph all arrive in that shape, so a script can test the exit code and read the line. Zero rows is not an error: it means the query matched nothing, and the Best Practices page has the usual reasons why.

Where next