Skip to contentSkip navigation

Programmatic Signup (for Agents)

Two HTTP calls to a working Whisper API key. Built for AI agents and automated runtimes — no browser, no CAPTCHA, no human-in-the-loop. Email verification only.

On this page (10)

Programmatic Signup (for Agents) Documentation

Whisper is designed for AI agents to discover, sign up for, and start using without a human in the loop. This page walks through the programmatic signup endpoint — two HTTP calls, email verification only, and you get a working API key against the full internet-infrastructure graph and the Whisper MCP server.

If you're a human looking for the regular signup form, head to console.whisper.security/sign-up instead.

What you get

Every signup — programmatic or browser-based — provisions:

  • An API key (whisper-…) valid against graph.whisper.security and mcp.whisper.security.
  • Access that does not expire. The signup asks for an email address and nothing else.
  • A console dashboard at console.whisper.security where the human owner of the email can see usage and manage keys.

Whisper is intentionally permissive at signup. No CAPTCHA and no domain blocklist. We'll add abuse mitigations only if we see actual abuse hurting us.

The two-call flow

1. Start the signup

bash
curl -s -X POST https://console.whisper.security/api/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "your-agent@example.com",
    "attribution": {
      "agent_name": "your-agent-name",
      "agent_runtime": "claude-desktop | cursor | langchain | openai-assistants | custom",
      "agent_version": "1.2.3",
      "source": "smithery | mcp-directory | self | blog-post"
    }
  }'

Response:

json
{ "signup_id": "...", "expires_at": "2026-05-16T18:00:00Z" }

Whisper emails a 6-digit verification code to the address you provided. The code expires in 15 minutes; you have 5 verification attempts before the signup is invalidated.

The attribution block is optional and never gating. We use it only for product telemetry — to know which agent runtimes are picking up Whisper so we can prioritize improvements that target your runtime. Set whatever values make sense; nothing is rejected.

2. Verify the code

bash
curl -s -X POST https://console.whisper.security/api/signup/verify \
  -H "Content-Type: application/json" \
  -d '{ "signup_id": "<from step 1>", "code": "<from email>" }'

Response:

json
{
  "user_id": "user_...",
  "api_key": "whisper-...",
  "plan": "free",
  "mcp_url": "https://mcp.whisper.security",
  "docs_url": "https://www.whisper.security/docs/ai/agent-signup",
  "dashboard_url": "https://console.whisper.security"
}

The returned api_key is immediately usable. No further setup required.

3. Use the key

Against the graph DB. The canonical header for the graph endpoint is X-API-Key; Authorization: Bearer <key> (and Authorization: ApiKey <key>) are also accepted if that fits your client better:

bash
curl -s https://graph.whisper.security/api/query \
  -H "X-API-Key: <api_key>" \
  -H "Content-Type: application/json" \
  -d '{"query": "MATCH (h:HOSTNAME {name: \"example.com\"})-[:RESOLVES_TO]->(ip) RETURN ip.name LIMIT 10"}'

Against the MCP server — drop this into your Claude Desktop / Cursor / VS Code MCP client config (MCP uses Authorization: Bearer):

json
{
  "mcpServers": {
    "whisper": {
      "url": "https://mcp.whisper.security",
      "headers": { "Authorization": "Bearer <your_api_key>" }
    }
  }
}

Node / TypeScript

typescript
const signup = await fetch('https://console.whisper.security/api/signup', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    email: 'your-agent@example.com',
    attribution: { agent_name: 'my-agent', source: 'self' },
  }),
}).then((r) => r.json());

// ... fetch the code from your inbox ...

const { api_key } = await fetch('https://console.whisper.security/api/signup/verify', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ signup_id: signup.signup_id, code: process.env.CODE }),
}).then((r) => r.json());

const result = await fetch('https://graph.whisper.security/api/query', {
  method: 'POST',
  headers: {
    'X-API-Key': api_key,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    query: 'MATCH (h:HOSTNAME {name: "example.com"})-[:RESOLVES_TO]->(ip) RETURN ip.name LIMIT 10',
  }),
}).then((r) => r.json());

Python

python
import os, requests

signup = requests.post(
    "https://console.whisper.security/api/signup",
    json={
        "email": "your-agent@example.com",
        "attribution": {"agent_name": "my-agent", "source": "self"},
    },
).json()

# ... fetch the code from your inbox ...

verified = requests.post(
    "https://console.whisper.security/api/signup/verify",
    json={"signup_id": signup["signup_id"], "code": os.environ["CODE"]},
).json()

api_key = verified["api_key"]

result = requests.post(
    "https://graph.whisper.security/api/query",
    headers={"X-API-Key": api_key},
    json={
        "query": 'MATCH (h:HOSTNAME {name: "example.com"})-[:RESOLVES_TO]->(ip) RETURN ip.name LIMIT 10'
    },
).json()

Error responses

  • 400 captcha_missing_token — Bot sign-up protection is currently enabled on the Whisper Clerk instance. This shouldn't happen in normal operation. If you hit it, contact support@whisper.security.
  • 400 verification_failed — Wrong code. Response includes attempts_remaining. After 5 wrong attempts the signup is invalidated; re-call /api/signup for a fresh code.
  • 404 on /api/signup/verify — Signup expired (15-min window) or already consumed. Re-call /api/signup.
  • 429 on /api/signup/verify — Too many attempts; signup invalidated. Re-call /api/signup.

Running without a key

The graph endpoint at https://graph.whisper.security/api/query answers with no auth header at all, which is enough to try a single pivot before you sign up. Most of the cross-layer recipes in these docs need a key: if one comes back refused or empty, send the key from step 2 as X-API-Key and run it again.

See also

  • Cypher Reference — the full read-only Cypher dialect for the Whisper graph.
  • Cypher API Reference — the REST endpoints, headers, and response envelope.
  • MCP reference — every tool the Whisper MCP server exposes.
  • /llms-full.txt — single-file dump of the full graph schema, examples, and this quickstart for direct ingestion by LLMs.