Graph Schema

How WhisperGraph is structured: the internet modeled as one connected graph, joined layer to layer. Start here, then drill into entities, connections, and pivots.

Updated July 2026Graph Schema

Graph Schema Documentation

WhisperGraph models the internet as one connected graph — every layer joined to the next, so a single query can walk from a web link to the physical building that routes it. This page is the map: the layers, how they connect, and where to go for the full reference. As of the latest sync the graph holds 39 node labels and 46 edge types, across ~7.4 billion nodes and ~39 billion edges.

The WhisperGraph schema — node labels and edge types pre-joined into one graph (a curated core of the model).

The layers

The graph is organized into layers, each a cluster of related entity types. The point of a pre-joined graph is that these layers are linked — you traverse across them in one query, not through separate lookups.

LayerWhat it holdsCore entities
Naming / DNSHostnames, the domain hierarchy, resolution, CNAME/NS/MXHOSTNAME, TLD
AddressingIPv4/IPv6 addresses and the CIDR prefixes they sit inIPV4, IPV6, PREFIX
Network / routingAutonomous systems, BGP announcements, peering, RPKIASN, ANNOUNCED_PREFIX, ROA
Ownership / WHOISRegistrants, registrars, contact email and phoneORGANIZATION, REGISTRAR, EMAIL, PHONE
GeoGeoIP city and countryCITY, COUNTRY
Email securitySPF, DMARC, DKIM, TLS fingerprintsHOSTNAME, DMARC_RECIPIENT, TLS_FINGERPRINT
Physical infrastructureData centers, IXPs, submarine cables, CDN PoPs, cloud regionsFACILITY, INTERNET_EXCHANGE, SUBMARINE_CABLE, CDN_POP, CLOUD_REGION
Threat intelligenceFeeds, categories, signals, Tor relaysFEED_SOURCE, CATEGORY, THREAT_SIGNAL_TYPE, TOR_RELAY
Threat actorsNamed actors and the MITRE ATT&CK techniques they useACTOR, ATTACK_PATTERN, THREAT_TAG

Every node carries a name property, and {name: "value"} lookups are indexed — anchoring on a name is the difference between an instant O(1) lookup and a full-graph scan.

How the layers connect

A hostname resolves down to an address, the address sits in a routed prefix, the prefix is announced by an autonomous system, and that system is physically present in a facility. Read top to bottom, that is a single traversal across four layers:

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, n.name LIMIT 5

That chain — and the dozens of others the graph supports — is what a flat lookup API cannot answer. The Pivoting Examples page collects the ones you will reach for most.

Where to go next

This section breaks the schema into three references:

  • Entities — every node label, what it represents, its counts, and the queryable properties (threat verdicts, BGP flags, RPKI fields).
  • Connection Types — every edge type, its direction, source and target labels, and the physical-vs-virtual rules that decide how you traverse it.
  • Pivoting Examples — the cross-layer chains, each with the traversal it encodes and a runnable query.

For the procedures that wrap common multi-step logic into a single CALL, see Procedures. For the query language itself, see the Cypher Reference.

Check the live schema

The counts on these pages are a snapshot and drift with each refresh. The db.* introspection procedures return the live label and edge sets, and never count against your quota:

CALL db.labels() YIELD label RETURN label ORDER BY label LIMIT 12
CallReturns
CALL db.labels()Every node label with its count.
CALL db.relationshipTypes()Every edge type with its source and target labels.
CALL db.propertyKeys()Every property name in use.
CALL db.schema()A structured overview of the whole graph, including traversalHints for virtual edges. Accepts a format argument ('json', 'markdown', or 'details').

GET /api/query/stats (see the API Reference) returns the live node and edge totals in one cheap call.