Skip to contentSkip navigation

Helpers — Naming & Lookups

The small utility procedures — registrable-apex and public-suffix tests, top-ASN ranking, and Tor and TLS-fingerprint lookups — each with the exact YIELD column names, because today you cannot write one without guessing.

Procedures
On this page (6)

Helpers — Naming & Lookups Documentation

Beyond the investigation and identity procedures, WhisperGraph ships a handful of small utilities — the naming, ranking, and lookup calls you reach for inside a larger query. None of them need a deep traversal; each answers one focused question. Every YIELD column named below came from a live call on 2026-08-09, so you can write the YIELD clause without guessing.

Public-suffix functions

The PSL functions apply the Public Suffix List so you can find the registrable apex of a hostname or test whether a label is itself a public suffix. They are the reliable way to reduce a messy hostname to the domain you actually want to anchor on.

cypher · runnablegraph.whisper.securitySign in to run
CALL whisper.psl.tldPlusOne("mail.google.co.uk") YIELD apex RETURN apex

FunctionArgumentYieldsReturns
whisper.psl.tldPlusOne(host)a hostnameapexthe registrable apex (mail.google.co.ukgoogle.co.uk)
whisper.psl.isPublicSuffix(label)a labelresulttrue if the label is itself a public suffix
whisper.psl.affiliation(host)exactly one hostfound, suffix, submitterLogin, submitterOrg, evidenceKind, confidencethe affiliation group for the host

whisper.psl.affiliation() takes exactly one argument; passing more returns a 400. Use tldPlusOne before an anchored lookup when your input might be a subdomain — anchoring on the apex is usually what you want.

whisper.topAsnsByPrefixCount(n)

Rank the autonomous systems announcing the most prefixes — a quick way to find the largest networks without scanning the ASN label.

cypher · runnablegraph.whisper.securitySign in to run
CALL whisper.topAsnsByPrefixCount(10) YIELD asn, prefixCount
RETURN asn, prefixCount ORDER BY prefixCount DESC

Tor & TLS-fingerprint lookups

Two direct lookups return the full record behind a Tor exit IP or a known TLS fingerprint, without composing the underlying edges yourself.

cypher · runnablegraph.whisper.securitySign in to run
CALL whisper.lookupTorRelay("185.220.101.1") YIELD indicator, found
RETURN indicator, found

ProcedureArgumentYieldsAnswers
whisper.lookupTorRelay(ip)an IPindicator, found, fingerprint, exitAddresses, exitAddressCount, exitAddressesV6, exitAddressCountV6, source, ingestedAtthe full Tor relay record for an exit IP
whisper.lookupTlsFingerprint(fingerprint)a JA3/JARM fingerprint (ja3: or jarm: prefixed)indicator, found, kind, hash, category, label, family, vendor, client, trustTier, sourceCount, firstSeen, lastSeen, licensePosturethe record for that TLS fingerprint

Both return found: false rather than zero rows when they have nothing, so the absence is always a populated row you can branch on.

TLS-fingerprint coverage is partial. Expect most indicators to return nothing. A zero-row result here means Whisper holds no observation — not that the host shares no infrastructure.

whisper.search(token)

When a token arrives unclassified — it could be an IP, hostname, ASN, CIDR, prefix, or suffix — whisper.search runs a bounded, type-aware lookup instead of an unanchored scan. It works out what the token is and looks it up as that node type, so it stays fast where a label-wide scan would run away.

cypher · runnablegraph.whisper.securitySign in to run
CALL whisper.search("185.220.101.1")
YIELD query, kind, name, matchedField, matchType
RETURN query, kind, name, matchedField, matchType

kind is the label it decided on (IPV4 here; HOSTNAME, ASN, and PREFIX are the others you will see), and matchType says whether the token hit a node exactly or was widened to find one. The procedure also declares a warning column, which stays empty on an exact hit and fills in when the lookup had to widen — prefix_expansion when a partial hostname was extended to a real one, for instance. Yield the columns you intend to read.

Once you know what the token is, anchor on it directly — whisper.search is the entry point, not the traversal.

whisper.version()

The liveness check. It reports the engine build answering your request, and it is the first thing to run when the graph is behaving oddly — a version string proves you reached the engine rather than something in front of it.

cypher · runnablegraph.whisper.securitySign in to run
CALL whisper.version() YIELD version, buildTime RETURN version, buildTime

Sample output (measured 2026-08-09):

json
[{"version": "<version>", "buildTime": "<iso-8601 timestamp>"}]

Quote the version when you report a problem: engine behaviour differs between builds, and the first question anyone will ask is which one you hit. CALL whisper.quota() is the companion call that tells you whether the server recognised your key at all.

Schema introspection

The db.* calls describe the live schema, and they are cheap — they answer immediately: db.labels(), db.relationshipTypes(), db.propertyKeys(), and db.schema(). db.schema() also accepts a format argument — db.schema('json'), db.schema('markdown'), or db.schema('details') — and db.schema.nodeTypeProperties() / db.schema.relTypeProperties() list the properties on each label and edge type. They are covered on the Graph Schema pages and in the Procedures overview.