# Getting Started

> Run your first WhisperGraph query without a key, then one request that crosses DNS, BGP routing, geo, and threat feeds.

*Source: https://www.whisper.security/docs/whisper-graph/getting-started*

---
Every investigation starts with an indicator: a hostname in a log, an IP on an alert. You need to know where it lives, who routes it, and whether anyone has flagged it. The first query below resolves a hostname to its IP addresses. The second follows those IPs on through routing, geography and threat feeds in one request, because in WhisperGraph the layers are already joined.

## Your first query

The API is one endpoint. `POST` a Cypher query as JSON to `https://graph.whisper.security/api/query`. This one resolves `github.com` to its IP addresses, and it runs without a key:

```bash
curl -s -A "whisper-client/1.0" \
  -X POST https://graph.whisper.security/api/query \
  -H "Content-Type: application/json" \
  -d '{"query": "MATCH (h:HOSTNAME {name: \"github.com\"})-[:RESOLVES_TO]->(ip:IPV4) RETURN ip.name AS ip LIMIT 5"}'
```

The answer is one JSON envelope: the column names, one object per row, and the server-side statistics.

```json
{
  "columns": ["ip"],
  "rows": [
    {"ip": "140.82.121.3"},
    {"ip": "140.82.121.4"},
    {"ip": "20.205.243.166"},
    {"ip": "4.228.31.150"}
  ],
  "statistics": {"rowCount": 4, "executionTimeMs": 7}
}
```

Two habits from the start: anchor on a `{name: "..."}` lookup, and end with a `LIMIT`. Both are why this answers in milliseconds. [Cypher](/docs/cypher) explains the dialect and [Best Practices](/docs/cypher/best-practices) the rest of the habits.

## Cross the layers

The walk below investigates `github.com` across the layers in one request: DNS resolution to its IPs, the BGP prefix announcing each IP and the network that routes it, the country each IP sits in, and any threat feeds that list it. A chain this deep needs a signed-in key, so [sign in](https://console.whisper.security/sign-in?redirect_url=https%3A%2F%2Fwww.whisper.security%2Fdocs%2Fwhisper-graph%2Fgetting-started) to run it here — there is no card to enter. Once it runs, open the widget's **Raw** view to see the exact response the API sent back.

```whisper-quickstart
{
  "cypher": "MATCH (h:HOSTNAME {name: \"github.com\"})-[:RESOLVES_TO]->(ip:IPV4)-[:ANNOUNCED_BY]->(p:ANNOUNCED_PREFIX)-[:ROUTES]->(a:ASN)\nOPTIONAL MATCH (a)-[:HAS_NAME]->(n:ASN_NAME)\nOPTIONAL MATCH (ip)-[:HAS_COUNTRY]->(co:COUNTRY)\nOPTIONAL MATCH (ip)-[:LISTED_IN]->(f:FEED_SOURCE)\nRETURN ip.name AS ip, p.name AS prefix, a.name AS asn, n.name AS network,\n       co.name AS country, collect(DISTINCT f.name)[0..5] AS feeds\nLIMIT 25",
  "prompt": "Investigate github.com: which IPs does it resolve to, which BGP prefix and network route each one, what country does each IP sit in, and are any of them listed on threat feeds?",
  "restNote": "The Raw tab shows the exact JSON envelope the API returns: columns, rows, and statistics."
}
```

Without a key, split the walk instead: take the IPs from the first query and ask the routing, geo and threat questions about them in follow-up requests, each anchored on an IP, or let a procedure such as `whisper.enrich()` do the join in one call. [Best Practices](/docs/cypher/best-practices) shows how to stage a traversal.

## Where next

- [Recipes](/docs/recipes): copy-paste investigations by job, from SOC triage to BGP and RPKI checks, each built from patterns like the ones above.
- [HTTP API](/docs/cypher-api): headers, the response envelope, parameter binding, and errors.
- [Graph schema](/docs/whisper-graph/schema): the 41 node labels and 52 edge types you can traverse.
