Procedures
What WhisperGraph's stored procedures do, how CALL works, and when a procedure beats a hand-written traversal.
Procedures Documentation
WhisperGraph ships stored procedures you call from Cypher with CALL. Each one wraps a multi-step computation — threat scoring, lookalike generation, WHOIS and BGP history, CDN origin discovery, infrastructure identity — into a single call that returns a clean result set instead of a hand-written traversal. They run on the public API at https://graph.whisper.security/api/query, and several have matching tools on the MCP server.
Scores and verdicts are live reads. The value reflects whatever data is loaded at query time, so treat a result as current, not fixed.
The four WhisperGraph procedures and the free metadata calls around them
Calling a procedure
CALL runs a procedure standalone, with YIELD to pick and filter columns, or once per row in the UNWIND ... CALL form. A standalone call with no YIELD returns every column the procedure produces. Full clause syntax is in Syntax & Clauses.
CALL whisper.variants("paypal.com")
YIELD variant, method, exists, confidenceLabel
WHERE exists
RETURN variant, method, confidenceLabel
LIMIT 6
The procedures
Four procedures do the heavy lifting, each with its own page. Beyond them, an identity family answers "whose infrastructure is this", and a set of helpers cover naming, quota, and lookups.
Investigation
| Procedure | What it answers | Notes |
|---|---|---|
explain(indicator) | Threat verdict for an IP, domain, ASN, or CIDR: score, level, factors[], sources[] | Auto-detects the indicator type |
whisper.variants(domain) | Typosquat and lookalike variants, filtered by default to ones registered in the graph | exists: true means registered, not malicious |
whisper.history(indicator) | WHOIS snapshots for a domain; BGP routing history for an IP, ASN, or prefix | Requires an API key |
whisper.origins(domain) | Candidate origin IPs behind a CDN or proxy, ranked by confidence | Passive lookup; no packet touches the target |
Identity & assessment
| Procedure | What it answers | Notes |
|---|---|---|
whisper.identify(hosts) | Whose infrastructure a host is — canonical name, category, roles | 1 to 256 hosts per call |
whisper.assess(hosts) | Whether a host is dangerous, qualified by coverage | Gate on coverage: no-data ≠ benign |
whisper.walk(host) | A bounded structural neighborhood when identify has no direct match | Depth- and budget-bounded |
Helpers
| Procedure | What it answers | Notes |
|---|---|---|
| PSL functions | Registrable apex and public-suffix tests | whisper.psl.tldPlusOne, whisper.psl.isPublicSuffix |
whisper.topAsnsByPrefixCount | The ASNs announcing the most prefixes | Ranked list |
| Tor / TLS lookups | Whether an IP runs a Tor relay or emits a known TLS fingerprint | whisper.lookupTorRelay, whisper.lookupTlsFingerprint |
whisper.quota() | Your plan tier and remaining quota | Does not count against quota |
db.labels(), db.relationshipTypes(), db.propertyKeys(), db.schema() | The live schema | Do not count against quota |
When to prefer a procedure over a traversal
Reach for the procedures first. They answer the hardest questions in one call, usually faster and cleaner than a hand-written deep traversal.
- The logic runs server-side.
explain()computes a score from feed count, feed weights, recency, and age, and hands back the arithmetic infactors[]with the named feeds insources[]. Reproducing that by walkingLISTED_INedges yourself takes more hops and gives you less evidence. - Procedures avoid timeouts. A query that runs too long returns HTTP 408. The standard fixes are: anchor the query, add a
LIMIT, or replace the scan with a procedure. See Best Practices. - The output is decision-ready. A procedure returns labeled columns you can paste straight into a ticket.
One caveat: BGP routing history over a large network is slow. Keep a LIMIT on whisper.history() calls and expect a longer round trip.
Quota and access
Metadata procedures are free: whisper.quota() and the db.* introspection calls never count against your quota.
CALL whisper.quota() YIELD key, value RETURN key, value
It yields plan, isAnonymous, hourlyLimit, hourlyUsed, hourlyRemaining, dailyLimit, maxQueryDepth, and maxResponseLimit.
Access differs by tier. Anonymous requests are capped at 2 traversal hops and cannot call advanced procedures such as whisper.history(). A free key raises the depth to 3 hops and unlocks the full procedure set; pass it in the X-API-Key header. Create a free account to get one. Rate limits and error shapes are covered in Errors & Rate Limits.
Schema introspection
The db.* procedures describe the live schema, so you can confirm a label or edge exists before you anchor on it.
CALL db.labels() YIELD label RETURN label ORDER BY label LIMIT 12
db.labels() lists every node label with its count. db.relationshipTypes() lists every edge type with its source and target labels. db.propertyKeys() lists every property name in use. db.schema() returns a structured overview of the whole graph and accepts a format argument ('json', 'markdown', or 'details'). The full label, edge, and property model is on the Graph Schema pages.