Whisper API
The REST endpoint in one screen: POST Cypher as JSON, pick an auth tier, read the response envelope.
Whisper API Documentation
The Whisper API is one HTTP endpoint. POST a read-only Cypher query as JSON to https://graph.whisper.security/api/query and you get back columns and rows. There is no SDK to install and no session to manage; curl, fetch, or any HTTP client works as is.
The same endpoint serves every tier, from anonymous exploration to paid plans, and every runnable example in these docs goes through it. A GET variant and a /api/query/stats endpoint exist for quick checks and graph-wide counts; the API Reference covers all three.
A Cypher query travels as a JSON POST to /api/query and returns columns, rows, and statistics.
Try it
One request end to end: resolve google.com to its IP addresses over the RESOLVES_TO edge. It is a single-hop lookup, so it runs without a key.
curl -s -X POST https://graph.whisper.security/api/query \
-H "Content-Type: application/json" \
-H "X-API-Key: $WHISPER_API_KEY" \
-d "{\"query\":\"MATCH (h:HOSTNAME {name: \\\"google.com\\\"})-[:RESOLVES_TO]->(ip:IPV4) RETURN ip.name AS ip LIMIT 5\"}"This one-hop lookup runs on the anonymous tier with no key. The Raw tab shows the exact JSON envelope the API returns: columns, rows, and statistics.grab a free API key →
Authentication
Send your key in the X-API-Key header. Authorization: Bearer <key> and Authorization: ApiKey <key> are also accepted. An invalid key does not fail the request; it degrades gracefully to the anonymous tier, so if results look shallower than expected, check the header first.
| Tier | Traversal depth | Notes |
|---|---|---|
| Anonymous | 2 hops | No header needed. Lower rate limits; advanced procedures such as whisper.history() are unavailable. |
| Free key | 3 hops | Higher rate limits and the full procedure set. Create a free key, no card required. |
| Paid | Deeper | Higher rates and larger result sets. Plan details live on the pricing page. |
CALL whisper.quota() returns the tier a request runs at and the caps that apply. Metadata procedures, including whisper.quota() and the db.* introspection calls, never count against your quota.
One practical header: production sits behind a WAF that rejects some default programmatic User-Agent strings with HTTP 403. Send an explicit User-Agent (any descriptive string) and you will not hit it.
The response envelope
Every successful query returns the same three fields:
| Field | What it holds |
|---|---|
columns | Column names, in RETURN order. |
rows | One object per row, keyed by column name. |
statistics | rowCount and server-side executionTimeMs. Network latency is not included. |
Errors come back as application/problem+json with a type, title, status, detail, and usually a suggestions array that proposes a rewrite. The full status table, rate-limit behavior, and quota rules live in Errors & Rate Limits.
Go deeper
- API Reference: the shared envelope, auth, pagination, and timeouts, with a page per endpoint — POST /api/query, GET /api/query, GET /api/query/stats — each with code in cURL, Python, Node, Go, and Ruby.
- Errors & Rate Limits: the problem+json shape, status codes,
Retry-After, and what does not count against quota. - Cypher Reference: the read-only dialect, its clauses and functions, and the golden rules that keep queries fast.