Cheat Sheet
One-page Cypher cheat sheet for WhisperGraph — schema, traversal chains, procedures, and the limits. Print-friendly.
Cheat Sheet Documentation
WhisperGraph is the internet as a queryable database — DNS, BGP/RPKI, WHOIS/RDAP, GeoIP, the web link graph, email posture, threat intel, and the physical internet, all pre-joined. This page is the dense quick-reference: labels, edges with directions, the traversal chains worth memorizing, procedure one-liners, and the limits. If you already know Cypher, this is the WhisperGraph-specific part you need. Deeper detail lives in the Graph Schema, Procedures, and the Use Cases.
Scale: ~7.4B nodes · ~39B edges · 43 threat feeds · 25 categories. GET /api/query/stats returns live totals.
Endpoint
POST https://graph.whisper.security/api/query
Content-Type: application/json
User-Agent: whisper-client/1.0 # send an explicit UA to avoid a WAF 403
X-API-Key: <your-key> # optional — anonymous works keyless (2-hop cap)
{"query": "MATCH (h:HOSTNAME {name:\"www.google.com\"})-[:RESOLVES_TO]->(ip) RETURN ip.name LIMIT 3"}
MCP for agents at https://mcp.whisper.security. See MCP setup. Full API details: Cypher API.
Node labels
There is no Domain or FQDN label — every name is a HOSTNAME. Every node has a name property. Labels marked (virtual) are synthesized at query time — reach them through an edge, never via a deep unanchored scan.
Core DNS & addressing — HOSTNAME (~2.6B), IPV4 (~619M), IPV6, PREFIX, ANNOUNCED_PREFIX (virtual), REGISTERED_PREFIX (virtual), TLD
Routing & org — ASN (AS13335), ASN_NAME, ORGANIZATION, TLD_OPERATOR
WHOIS & registration — REGISTRAR, EMAIL, PHONE, RDAP_ENTITY
Geo & DNSSEC — CITY, COUNTRY, DNSSEC_ALGORITHM
Threat intel — FEED_SOURCE (43, virtual), CATEGORY (25, virtual), THREAT_TAG (MISP-galaxy), THREAT_SIGNAL_TYPE, ACTOR (APT28), ATTACK_PATTERN (MITRE ATT&CK)
RPKI & routing observations — ROA, BGP_PATH_OBSERVATION
Physical infrastructure — FACILITY, INTERNET_EXCHANGE, SUBMARINE_CABLE, CABLE_LANDING, CDN_POP, DNS_ROOT_INSTANCE, CLOUD_REGION (aws:eu-west-1)
Egress, fingerprint & transparency — VENDOR, TOR_RELAY, TLS_FINGERPRINT (JA3/JARM), CT_OBSERVATION, DMARC_RECIPIENT
Edge types — with directions
Directions are strict: a wrong-way traversal returns zero rows with no error. The arrow below is the stored direction; traverse backwards with <-[:EDGE]-.
DNS & web
| Edge | From → To | Notes |
|---|---|---|
RESOLVES_TO | HOSTNAME → IPV4/IPV6 | Forward only. Reverse DNS: (ip)<-[:RESOLVES_TO]-(h) |
ALIAS_OF | HOSTNAME → HOSTNAME | CNAME |
CHILD_OF | HOSTNAME/EMAIL → HOSTNAME/TLD | child → parent (var-length walks reach the TLD) |
NAMESERVER_FOR | HOSTNAME → HOSTNAME | server → domain. A domain's NS: (d)<-[:NAMESERVER_FOR]-(ns) |
MAIL_FOR | HOSTNAME → HOSTNAME | server → domain. A domain's MX: (d)<-[:MAIL_FOR]-(mx) |
LINKS_TO | HOSTNAME → HOSTNAME | Web hyperlink (the largest edge type) |
BGP, routing & RPKI
| Edge | From → To | Notes |
|---|---|---|
BELONGS_TO | IPV4/IPV6 → PREFIX | RIR allocation (also FEED_SOURCE → CATEGORY) |
ANNOUNCED_BY | IPV4/IPV6 → ANNOUNCED_PREFIX | virtual |
ROUTES | ASN → ANNOUNCED_PREFIX/PREFIX | virtual |
HAS_NAME | ASN → ASN_NAME | asn.name is the AS number; network name is on ASN_NAME (virtual) |
PEERS_WITH | ASN ↔ ASN | symmetric — matches either arrow |
CONFLICTS_WITH | ANNOUNCED_PREFIX → ASN | MOAS conflict (virtual) |
ROA_AUTHORIZES_ORIGIN | ROA → ASN | RPKI authorizes origin AS |
ROA_AUTHORIZES_PREFIX | ROA → PREFIX | RPKI authorizes prefix |
OPERATES | TLD_OPERATOR → TLD | Registry operator |
WHOIS & registration
| Edge | From → To | Notes |
|---|---|---|
HAS_REGISTRAR | HOSTNAME → REGISTRAR | Current registrar |
PREV_REGISTRAR | HOSTNAME → REGISTRAR | Historical — track transfers |
HAS_EMAIL | HOSTNAME → EMAIL | WHOIS contact |
HAS_PHONE | HOSTNAME → PHONE | WHOIS contact |
REGISTERED_BY | HOSTNAME/ASN/PREFIX → ORGANIZATION | Registrant / owning org |
SAME_ORG_AS | ORGANIZATION → ORGANIZATION | Entity reconciliation |
Geo
| Edge | From → To | Notes |
|---|---|---|
LOCATED_IN | IPV4/IPV6 → CITY | Chain HAS_COUNTRY for the country |
HAS_COUNTRY | ASN/CITY/IPV4/PHONE → COUNTRY | Country code |
Threat intel & egress
| Edge | From → To | Notes |
|---|---|---|
LISTED_IN | IPV4/IPV6/HOSTNAME → FEED_SOURCE | Carries firstSeen/lastSeen/weight (virtual) |
HAS_SIGNAL | IPV4/IPV6/HOSTNAME/ASN/PREFIX → THREAT_SIGNAL_TYPE | Threat signal |
OPERATES_EXIT_NODE | IPV4 → TOR_RELAY | Tor-exit identity |
DELEGATED_TO | PREFIX/IPV4/VENDOR → VENDOR | Cloud/SaaS operator (distinct from WHOIS owner) |
USES_TECHNIQUE | ACTOR → ATTACK_PATTERN | Adversary TTPs |
Email security (SPF / DMARC / DKIM)
| Edge | From → To | Notes |
|---|---|---|
SPF_INCLUDE | HOSTNAME → HOSTNAME | include: |
SPF_IP | HOSTNAME → IPV4/IPV6/PREFIX | ip4:/ip6: |
SPF_A / SPF_MX / SPF_EXISTS / SPF_REDIRECT | HOSTNAME → HOSTNAME | Other SPF mechanisms |
DMARC_REPORTS_TO | HOSTNAME → DMARC_RECIPIENT | Where DMARC reports go |
DKIM_SIGNED_BY | HOSTNAME → VENDOR | Mail vendor whose key signs the domain |
EMITS_TLS_FINGERPRINT | IPV4 → TLS_FINGERPRINT | JA3/JARM |
Physical infrastructure & CT
| Edge | From → To | Notes |
|---|---|---|
AS_PRESENT_AT | ASN → FACILITY | Network in a datacenter |
IX_MEMBER | ASN → INTERNET_EXCHANGE | Network at an IXP |
IX_HOSTED_AT | INTERNET_EXCHANGE → FACILITY | IXP's building |
CABLE_LANDS_AT | SUBMARINE_CABLE → CABLE_LANDING | Subsea cable landing |
LANDING_NEAR | CABLE_LANDING → FACILITY | Landing near a facility |
CDN_POP_AT | CDN_POP → FACILITY | CDN PoP in a facility |
FIBER_SEGMENT | FACILITY → FACILITY | Fiber link |
PREFIX_IN_REGION | PREFIX → CLOUD_REGION | Prefix in a cloud region |
SEEN_IN_CT | HOSTNAME → CT_OBSERVATION | Subdomain/SAN discovery |
Virtual edges:
ROUTES,HAS_NAME,CONFLICTS_WITH,ANNOUNCED_BY, andBELONGS_TO → CATEGORYare synthesized at query time. Write them as explicit single hops — never inside a variable-length[*1..N]pattern.
Direction landmines (memorize these)
| Edge | Right way |
|---|---|
RESOLVES_TO | HOSTNAME → IPV4. No PTR edge — reverse with (ip)<-[:RESOLVES_TO]-(h) |
MAIL_FOR / NAMESERVER_FOR | server → domain. A domain's MX/NS: (d)<-[:MAIL_FOR]-(mx) |
CHILD_OF | child → parent |
PEERS_WITH | symmetric — (asn)-[:PEERS_WITH]-(peer) matches either way |
LOCATED_IN | IPV4 → CITY, then CITY-[:HAS_COUNTRY]->COUNTRY (no IP→COUNTRY shortcut) |
Must-know traversal chains
Host → network owner (attribution) — who hosts a domain and on whose AS:
MATCH (h:HOSTNAME {name:"github.com"})-[:RESOLVES_TO]->(ip:IPV4)
-[:ANNOUNCED_BY]->(ap:ANNOUNCED_PREFIX)-[:ROUTES]->(a:ASN)-[:HAS_NAME]->(n:ASN_NAME)
RETURN ip.name, ap.name, a.name AS asn, n.name AS network LIMIT 5
IP → jurisdiction — (:IPV4)-[:LOCATED_IN]->(:CITY)-[:HAS_COUNTRY]->(:COUNTRY)
Blast radius (one indicator → the campaign) — pivot on shared infra:
MATCH (ip:IPV4 {name:"203.0.113.10"})<-[:RESOLVES_TO]-(h:HOSTNAME)
OPTIONAL MATCH (h)-[:HAS_EMAIL]->(e:EMAIL)<-[:HAS_EMAIL]-(sibling:HOSTNAME)
RETURN h.name, e.name, collect(DISTINCT sibling.name)[..20] AS shared_registrant LIMIT 25
Domain → mail / name servers (reverse traversal) — MATCH (d:HOSTNAME {name:"github.com"})<-[:MAIL_FOR]-(mx) RETURN mx.name LIMIT 10
MOAS / possible BGP hijack — MATCH (p:ANNOUNCED_PREFIX {name:"216.168.228.0/24"})-[:CONFLICTS_WITH]->(a:ASN) RETURN p.name, collect(a.name) LIMIT 25
IP → feeds → categories — (:IPV4)-[:LISTED_IN]->(:FEED_SOURCE)-[:BELONGS_TO]->(:CATEGORY)
ASN → physical footprint — (:ASN)-[:AS_PRESENT_AT]->(:FACILITY) and (:ASN)-[:IX_MEMBER]->(:INTERNET_EXCHANGE)-[:IX_HOSTED_AT]->(:FACILITY)
Actor → ATT&CK — MATCH (a:ACTOR {name:"APT28"})-[:USES_TECHNIQUE]->(t:ATTACK_PATTERN) RETURN t.name LIMIT 25
The Use Cases have copy-paste recipes per workflow.
Threat properties on a node
Threat-listed IPV4 / IPV6 / HOSTNAME nodes carry the verdict inline, so one anchored read gives the whole posture — no extra hops:
MATCH (ip:IPV4 {name:"185.220.101.1"})
RETURN ip.threatScore, ip.threatLevel, ip.isThreat, ip.isTor, ip.isAnonymizer LIMIT 1
threatScore(numeric),threatLevel(NONE…CRITICAL), and the flagsisThreat,isTor,isAnonymizer.- For the scored reasoning — feeds, weights, factors — call
explain(). ANONE/clean read means "not listed at this granularity," not "safe."
Procedures — one-liners
Call from Cypher with CALL. Full signatures in Procedures.
| Procedure | One-liner |
|---|---|
explain("indicator") | Scored verdict + factors[] + sources[] — IP, host, ASN, or CIDR. Evidence chain, not a black box |
whisper.variants("domain") | Typosquats across many algorithms; returns registered lookalikes by default |
whisper.history("indicator") | WHOIS history (domain) or BGP history (IP/ASN/prefix). Needs a key |
whisper.origins("domain") | Discover the real origin IPs behind a CDN/proxy |
whisper.quota() | Plan, hourly/daily limits, maxQueryDepth — free, doesn't count against quota |
db.labels() / db.relationshipTypes() / db.schema() | Introspect the live schema before anchoring — don't count against quota |
explain()auto-detects the indicator type.exists: truefromwhisper.variants()means registered, not malicious — pivot the hit throughexplain()for a verdict.
Query rules (one line each)
| Do this | Not that |
|---|---|
Anchor on name: MATCH (h:HOSTNAME {name:"example.com"}) | MATCH (h:HOSTNAME) WHERE h.name = "example.com" |
Prefix match: WHERE h.name STARTS WITH "mail." | Regex: WHERE h.name =~ "^mail\\..*" |
Suffix match: WHERE h.name ENDS WITH ".example.com" | Broad ENDS WITH "example.com" (scan) |
Always add LIMIT | Open-ended traversal on a billion-node label |
GET /api/query/stats for global counts | MATCH ()-[r]->() RETURN count(r) |
OPTIONAL MATCH for sparse WHOIS fields | Mandatory MATCH (drops rows silently) |
Confirm with CALL db.labels() before anchoring | Guessing a Domain/fqdn that doesn't exist |
Single explicit hops for virtual edges (ROUTES, HAS_NAME, CONFLICTS_WITH) | Virtual edges inside [*1..N] |
CALL explain(ip) for scoring | Manual ASN→PREFIX→IP→LISTED_IN walks (time out on big nets) |
Speed guide: anchored point lookups = instant · STARTS WITH / selective ENDS WITH ".dom" = fast · multi-hop + OPTIONAL MATCH = 1–5s · LINKS_TO traversals and full HOSTNAME scans = slow · unanchored label scans and regex =~ on HOSTNAME = avoid.
Access & limits
| Tier | Hop cap | Notes |
|---|---|---|
| Anonymous | 2 hops | Keyless. No whisper.history. Quick sanity check |
| Free key | 3 hops | All procedures |
| Paid | deeper | See pricing |
Check yours with CALL whisper.quota() YIELD key, value RETURN key, value. Get a free key · Pricing.
# keyless 2-hop sanity check
curl -s -A "whisper-client/1.0" https://graph.whisper.security/api/query \
-H "Content-Type: application/json" \
-d '{"query":"MATCH (h:HOSTNAME {name:\"www.google.com\"})-[:RESOLVES_TO]->(ip) RETURN h.name, ip.name LIMIT 3"}'
See also the Threat Feeds & Categories reference (43 feeds / 25 categories) and the Cypher API for the full endpoint reference.