New

Procedure Reference

Every WhisperGraph stored procedure — explain, variants, history, origins, the Indenture identity/verdict arms, quota, and schema introspection — with signatures and return shapes.

Updated June 2026

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 (NONECRITICAL), 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. Returns canonical_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 by coverage (known-clean / structural-only / no-data). Returns band, coverage, sub_labels[], signals[], evidence[]. Gate on coverage: no-data means unknown, not benign.

  • whisper.walk(host [, depth] [, budgetMs]) — structural neighborhood (siblings, nearest known vendors) when identify has no direct match. Read arms.deadline_hit before treating an empty siblings list 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.ukgoogle.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.