Procedure Reference
Every WhisperGraph stored procedure — explain, variants, history, origins, the Indenture identity/verdict arms, quota, and schema introspection — with signatures and return shapes.
Procedure Reference Documentation
WhisperGraph ships a set of stored procedures you call from Cypher with CALL. They wrap the multi-step logic behind threat scoring, typosquat generation, WHOIS/BGP history, CDN de-cloaking, and infrastructure identity so you get a clean result set instead of hand-writing the traversal. Each one below is live on the public graph at https://graph.whisper.security/api/query — most also have a matching tool on the AI Context (MCP) surface.
Every example is reproducible with a free API key (a few need a key and won't run on the anonymous tier — noted inline). Scores and verdicts are live reads: the value reflects whatever data is loaded at query time, so treat it as current, not fixed.
explain — threat verdict with evidence
CALL explain(indicator) — auto-detects an IP, IPv6, hostname, ASN, or CIDR and returns a scored assessment plus the evidence behind it.
Returns: indicator, type, found, score, level (NONE…CRITICAL), explanation, factors[] (the scoring arithmetic), sources[] (each feed with its weight and first/last-seen).
CALL explain("185.220.101.1")
YIELD score, level, factors, sources
RETURN score, level, factors, sources
The score combines feed count, each feed's weight, a recency boost, and an age boost — an inspectable chain you can paste into a ticket. The same call works on a domain, ASN, or CIDR. For a single node you can also read the verdict properties directly: MATCH (ip:IPV4 {name:"..."}) RETURN ip.verdictScore, ip.verdictLevel, ip.verdictBlocking.
whisper.variants — typosquat / lookalike generation
CALL whisper.variants(domain [, label] [, includeNonExistent]) — runs the domain through 14+ generation algorithms (omission, repetition, transposition, keyboard-adjacent, homoglyph, bitsquatting, TLD swap, …) and, by default, returns only the variants that exist as nodes.
Returns: variant, method, exists, confidence, confidenceLabel.
CALL whisper.variants("paypal.com")
YIELD variant, method, exists, confidenceLabel
WHERE exists
RETURN variant, method, confidenceLabel
LIMIT 10
exists: true means registered, not malicious — pivot each hit through explain() for a verdict. Pass a label as the second argument to check a different node type, or false to return every generated variant. (Also the domain_variants MCP tool.)
whisper.history — WHOIS & BGP history
CALL whisper.history(indicator) — returns timestamped snapshots. For a domain it returns WHOIS history (createDate, updateDate, registrar, registrant, nameServers); for an IP / ASN / prefix it returns BGP routing history (origin, prefix, visibility). Requires an API key (not on the anonymous tier).
CALL whisper.history("google.com")
YIELD createDate, updateDate, registrar, nameServers
RETURN createDate, updateDate, registrar, nameServers
LIMIT 3
BGP history over a large network can take several seconds — keep a LIMIT on it.
whisper.origins — de-cloak CDN/proxy origins
CALL whisper.origins(domain) — finds candidate real origin IPs behind a CDN or proxy, derived from MX/SPF/sibling and crawl signals.
Returns: ip, confidence, methods[], asn, asnName — highest confidence first.
CALL whisper.origins("cloudflare.com")
YIELD ip, confidence, methods, asn, asnName
RETURN ip, confidence, methods, asn, asnName
LIMIT 5
Indenture — identity, coverage, neighborhood
The Indenture procedures answer whose infrastructure is this and is it dangerous as separate questions. Identity is not a verdict — a host on a big cloud isn't malicious because the cloud also hosts malware.
-
whisper.identify(hosts)— whose infrastructure. Returnscanonical_name,category,roles[],host_class(e.g.multi_tenant_user_content,dedicated, cloud, CDN),confidence,evidence[]. Accepts 1–256 hosts.CALL whisper.identify(["github.com"]) YIELD host, canonical_name, host_class, roles RETURN host, canonical_name, host_class, roles -
whisper.assess(hosts)— is it dangerous, qualified bycoverage(known-clean/structural-only/no-data). Returnsband,coverage,sub_labels[],signals[],evidence[]. Gate oncoverage:no-datameans unknown, not benign. -
whisper.walk(host [, depth] [, budgetMs])— structural neighborhood (siblings, nearest known vendors) whenidentifyhas no direct match. Readarms.deadline_hitbefore treating an emptysiblingslist as "no neighbors".
(These map to the identify / assess / walk MCP tools.)
whisper.quota — your plan & limits
CALL whisper.quota() returns your plan tier and remaining quota. It does not count against quota.
CALL whisper.quota() YIELD key, value RETURN key, value
Yields plan, isAnonymous, hourlyLimit/hourlyUsed/hourlyRemaining, dailyLimit, maxQueryDepth, maxResponseLimit.
Public-suffix & ASN helpers
whisper.psl.tldPlusOne(name)YIELD apex— the registrable apex of a hostname (mail.google.co.uk→google.co.uk).whisper.psl.isPublicSuffix(name)tests whether a label is itself a public suffix.whisper.topAsnsByPrefixCount()— the ASNs announcing the most prefixes.
Schema introspection (db.*)
Confirm a label, edge, or property exists before you anchor on it. These don't count against quota.
CALL db.labels() YIELD label RETURN label ORDER BY label // every label + count
CALL db.relationshipTypes() YIELD type RETURN type ORDER BY type // every edge type
CALL db.propertyKeys() YIELD propertyKey RETURN propertyKey // every property name
CALL db.schema() // structured overview
Checking db.labels() / db.relationshipTypes() first is the fastest cure for the most common mistake — anchoring on a label or edge that doesn't exist and getting silent empty results.
For the full label/edge/property model see the Graph Schema. For capabilities that aren't yet live on the public graph, see Coming to the graph.