Whisper API

The keyless half of the platform as an OpenAPI 3.1.0 contract (info.version 1.1.0, 13 operations, served at https://whisper.online/openapi.json and byte-identically on agents. and endpoint.whisper.online): the single Cypher endpoint POST /api/query (keyless graph reads; with X-API-Key the whole control plane via CALL whisper.agents), the A2A JSON-RPC endpoint POST /a2a, GET /verify-identity, the RFC 6962 transparency ledger (checkpoint, key, status-list, OpenTimestamps anchor, tiles, inclusion and consistency proofs), the live service catalogue GET /menu, and the two discovery documents. The spec deliberately excludes surfaces another standard already specifies (DoH, RDAP, geofeed, security.txt, SSF, SCITT, the agent card, MCP) and points at those standards instead.

Operations 13

POST /api/query The one Cypher endpoint: graph reads, and the entire control plane #
POST /a2a A2A JSON-RPC endpoint #
GET /verify-identity Verify an address is a real Whisper agent identity #
GET /checkpoint Signed checkpoint of the identity transparency ledger #
GET /checkpoint/key The public key the checkpoint is signed with #
GET /checkpoint/status-list Revocation status list for issued identities #
GET /checkpoint/ots/latest-confirmed Latest OpenTimestamps-confirmed checkpoint #
GET /tile/{level}/{index} A Merkle tile of the ledger #
GET /inclusion Inclusion proof for one ledger leaf #
GET /consistency Consistency proof between two checkpoints #
GET /menu Every service that is live right now #
GET /.well-known/agent-card.json A2A Agent Card #
GET /.well-known/agent-onboarding.json Machine-readable onboarding manifest #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/whisper-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

whisper-online-openapi.json Raw ↑
{
  "openapi": "3.1.0",
  "info": {
    "title": "Whisper",
    "summary": "Identity and safe egress for AI agents, and the security graph behind it.",
    "description": "Every endpoint described here was exercised live before this document was written.\n\n**This document describes only the surfaces that have no other machine-readable spec.** Several of the most important things Whisper serves are defined by somebody else's standard, and restating a standard in our own words creates a second, staler copy of it. Those are listed under `externalDocs` and in the table below, with a pointer to the specification rather than a paraphrase:\n\n| Surface | Where | Specification |\n| --- | --- | --- |\n| DNS over HTTPS | `/dns-query`, `/doh` on the resolver hosts | RFC 8484 |\n| RDAP | `https://rdap.whisper.online/ip/{address}` | RFC 9083 / 7480 |\n| Geofeed | `/.well-known/geofeed` | RFC 9092 |\n| Security contact | `/.well-known/security.txt` | RFC 9116 |\n| Shared signals (CAEP/SSF) | `/.well-known/ssf-configuration` | OpenID SSF |\n| Transparency statements | `/.well-known/scitt-keys`, `/entries` | IETF SCITT |\n| Agent Card | `/.well-known/agent-card.json` | A2A 1.0 |\n| MCP server | `https://mcp.whisper.security` | Model Context Protocol |\n\n**The control plane is deliberately ONE endpoint.** Provisioning and governance do not get a verb each: they ride a single Cypher call, `POST /api/query` with `CALL whisper.agents({op:'...', args:{...}})`. That is the architecture, not a shortcut in this document, and it means a new capability needs no new URL to discover.\n\nWhat is left, and what this file actually specifies, is the keyless half that exists so someone who has never heard of us can check our claims with no account and no client: verification, the append-only identity ledger, and the live service catalog.",
    "version": "1.1.0",
    "contact": {
      "name": "Whisper Security",
      "url": "https://whisper.online"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://whisper.online/terms"
    }
  },
  "servers": [
    {
      "url": "https://whisper.online",
      "description": "The main site, verification, and the ledger"
    }
  ],
  "externalDocs": {
    "description": "The full catalog, written for agents",
    "url": "https://whisper.online/llms-full.txt"
  },
  "components": {
    "securitySchemes": {
      "whisperApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "A whisper_live_... key. Obtainable from an email address alone, with no human step; see /.well-known/agent-onboarding.json."
      }
    }
  },
  "paths": {
    "/api/query": {
      "servers": [
        {
          "url": "https://graph.whisper.online",
          "description": "The control plane and graph front door"
        }
      ],
      "post": {
        "summary": "The one Cypher endpoint: graph reads, and the entire control plane",
        "description": "Keyless for graph reads (`CALL whisper.assess($a)`, `identify`, `walk`, `origins`, ...). With `X-API-Key` the same endpoint is the control plane: `CALL whisper.agents({op:'register'|'identity'|'connect'|'policy'|'logs'|'revoke'|'list'|..., args:{...}})`. Always bind values as parameters; never concatenate them into the query text.",
        "operationId": "query",
        "security": [
          {},
          {
            "whisperApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "string"
                  },
                  "parameters": {
                    "type": "object"
                  },
                  "timeout": {
                    "type": "integer",
                    "description": "Milliseconds."
                  }
                }
              },
              "examples": {
                "keyless graph read": {
                  "value": {
                    "query": "CALL whisper.assess($a)",
                    "parameters": {
                      "a": "example.com"
                    }
                  }
                },
                "keyed control call": {
                  "value": {
                    "query": "CALL whisper.agents($a)",
                    "parameters": {
                      "a": {
                        "op": "register",
                        "args": {
                          "label": "my-agent"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "columns / rows / statistics.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "columns": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "statistics": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed query, bad arguments, or an op outside the allowlist."
          },
          "403": {
            "description": "The key lacks the scope the op requires."
          }
        }
      }
    },
    "/a2a": {
      "post": {
        "summary": "A2A JSON-RPC endpoint",
        "description": "JSON-RPC 2.0, A2A 1.0. The method is `SendMessage`. Keyless skills answer with no credential; control skills need `X-API-Key` and are a binding over the same Cypher call above, not a second implementation of it. The Agent Card at /.well-known/agent-card.json lists every skill.",
        "operationId": "a2aSendMessage",
        "security": [
          {},
          {
            "whisperApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jsonrpc",
                  "method"
                ],
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "const": "2.0"
                  },
                  "id": {},
                  "method": {
                    "type": "string",
                    "example": "SendMessage"
                  },
                  "params": {
                    "type": "object"
                  }
                }
              },
              "example": {
                "jsonrpc": "2.0",
                "id": 1,
                "method": "SendMessage",
                "params": {
                  "message": {
                    "messageId": "m1",
                    "role": "ROLE_USER",
                    "parts": [
                      {
                        "data": {
                          "skill": "assess",
                          "input": "example.com"
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A JSON-RPC result, or a JSON-RPC error object.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Unparseable, or not a JSON-RPC request."
          }
        }
      }
    },
    "/verify-identity": {
      "get": {
        "summary": "Verify an address is a real Whisper agent identity",
        "description": "Keyless. Answers honestly for an address that is not, or is no longer, allocated rather than inventing a record.",
        "operationId": "verifyIdentity",
        "security": [],
        "parameters": [
          {
            "name": "address",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "2a04:2a01:aeee:42b6:41cc:e09:c971:41a1"
          }
        ],
        "responses": {
          "200": {
            "description": "The verdict and its evidence.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "is_whisper_agent": {
                      "type": "boolean"
                    },
                    "evidence": {
                      "type": "object"
                    },
                    "detail": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "No address given."
          }
        }
      }
    },
    "/checkpoint": {
      "get": {
        "summary": "Signed checkpoint of the identity transparency ledger",
        "operationId": "ledgerCheckpoint",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "Keyless. A signed note in the C2SP checkpoint format: origin, tree size, root hash, signature."
      }
    },
    "/checkpoint/key": {
      "get": {
        "summary": "The public key the checkpoint is signed with",
        "operationId": "ledgerCheckpointKey",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        },
        "description": "Keyless, so the signature above can be verified without trusting this API."
      }
    },
    "/checkpoint/status-list": {
      "get": {
        "summary": "Revocation status list for issued identities",
        "operationId": "ledgerStatusList",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/checkpoint/ots/latest-confirmed": {
      "get": {
        "summary": "Latest OpenTimestamps-confirmed checkpoint",
        "operationId": "ledgerOtsLatestConfirmed",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "description": "Keyless. Anchors the ledger in an external timestamp so freshness does not rest on our word."
      }
    },
    "/tile/{level}/{index}": {
      "get": {
        "summary": "A Merkle tile of the ledger",
        "operationId": "ledgerTile",
        "security": [],
        "description": "Keyless. Tiles let a verifier reconstruct and check the tree itself.",
        "parameters": [
          {
            "name": "level",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "index",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "000"
          }
        ],
        "responses": {
          "200": {
            "description": "Tile bytes.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    },
    "/inclusion": {
      "get": {
        "summary": "Inclusion proof for one ledger leaf",
        "operationId": "ledgerInclusion",
        "security": [],
        "description": "Keyless. Proves a specific identity statement is in the tree the checkpoint commits to.",
        "parameters": [
          {
            "name": "leaf",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A leaf index (0 <= N < tree_size), or a 64-hex statement digest.",
            "example": "0"
          }
        ],
        "responses": {
          "200": {
            "description": "The proof.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Missing or malformed leaf."
          }
        }
      }
    },
    "/consistency": {
      "get": {
        "summary": "Consistency proof between two checkpoints",
        "operationId": "ledgerConsistency",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "description": "Keyless. Proves the ledger is append-only: an earlier tree is a prefix of a later one."
      }
    },
    "/menu": {
      "get": {
        "summary": "Every service that is live right now",
        "operationId": "menu",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "description": "Generated from the same canonical list the code dispatches from, so it cannot describe a verb we do not serve. Queried from inside your own tunnel it answers with your personalized URLs."
      },
      "servers": [
        {
          "url": "https://menu.whisper.online",
          "description": "The live service catalog"
        }
      ]
    },
    "/.well-known/agent-card.json": {
      "get": {
        "summary": "A2A Agent Card",
        "operationId": "agentCard",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "description": "Every skill, which half is keyless, and the JSON-RPC endpoint that serves them."
      }
    },
    "/.well-known/agent-onboarding.json": {
      "get": {
        "summary": "Machine-readable onboarding manifest",
        "operationId": "agentOnboarding",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "description": "The structured form of the journey from an email address to a working, routable identity."
      }
    }
  }
}