Zapier
Verify, provision, and govern Whisper agent identities from a Zap — no server, no SDK, two tiers.
The pain
Your ops team lives in Zapier. A support ticket lands, a Stripe payment clears, a row appears in a sheet — and somewhere downstream you need to know "is the bot that just called our webhook actually one of ours?", or you need to mint a fresh agent identity the moment a new customer signs up, without anyone touching a terminal. Rolling that yourself means a webhook step that shells out to curl, hand-rolled JSON for a Cypher-shaped control API, and an API key pasted in plaintext into a "Webhooks by Zapier" action where every collaborator on the Zap can see it. That's the wrong shape for both halves of the problem: identity verification shouldn't need a credential at all, and agent provisioning shouldn't need you to hand-write a POST body. The Zapier app collapses both into typed fields — a Search step for "look this address up," a Create step for "make this happen" — and keeps your key exactly where Zapier keeps secrets: in the connection, never in a Zap's visible steps.
Two tiers, one connection
The app follows the same Robustness Principle as every other Whisper surface: liberal in what it accepts. The connection's API-key field is optional.
- No key — the four Searches work immediately: verify an IPv6 address is a genuine Whisper agent, pull its RDAP record, walk its certificate-transparency history, see who's been looking it up. Read-only, anonymous, zero setup.
- With your
whisper_live_...key — the same connection also unlocks three Creates: register a new agent (mints a/128, hostname, RDAP record, and its own key), set your tenant's DNS policy, and revoke an agent. Irreversible actions stay gated behind the key; nothing mutates without one.
A blank connection is a valid connection — the test step succeeds either way, so a teammate can wire up verification Zaps today and an admin can drop in a key later to unlock provisioning, with no re-plumbing. This is exactly the two-tier design also used by the n8n and Make integrations — pick whichever automation tool your team already runs.
The Searches (keyless)
Every Search takes one IPv6 address and hits the public identity API at rdap.whisper.online — no key, ever:
| Search | Endpoint | Returns |
|---|---|---|
| Verify Agent Identity | GET /verify-identity?ip={addr} |
is_whisper_agent, DANE/JWS verdicts, evidence bundle |
| Lookup RDAP Record | GET /ip/{addr} |
the RFC 9083 registry object |
| Get Transparency Log | GET /ip/{addr}/transparency |
certificate-issuance history |
| Get Inbound Lookups | GET /ip/{addr}/lookups |
who has been resolving this agent |
Two design details matter more than they look:
- "Not a Whisper agent" is data, not an error.
verify-identityanswers a negative with HTTP 404 and a full JSON verdict body — the Zapier app treats both 200 and 404 as one successful Search record, so you branch onis_whisper_agentin the Zap editor instead of catching an exception. A malformed address (HTTP 400) or an upstream failure (5xx) does throw, with the API's own message surfaced verbatim — never a bare "unexpected error." - RDAP lookups return nothing, cleanly, on a miss. A 404 from
/ip/{addr}becomes an empty Search result, which is exactly what Zapier's "only continue if found" and "find or create" patterns expect.
Input is normalized before it ever leaves the Zap: compressed or expanded IPv6, a stray /128 suffix, surrounding whitespace, an IPv6 zone id — all accepted. Every value that reaches the control plane is escaped through a Cypher-literal escaper (quotes and backslashes doubled), so nothing you paste from a webhook payload can break out of the query.
The Creates (need your key)
Each Create runs the one control verb, CALL whisper.agents({op:'…', args:{…}}), over POST https://graph.whisper.security/api/query — the same call the whisper CLI and every SDK make, just wrapped in typed Zap fields:
| Create | Op | Fields | What it does |
|---|---|---|---|
| Register Agent | register |
Name, Contact Email (optional) | Mints a /128, agents.whisper.online hostname, PTR, RDAP record, and the agent's own API key — returned once |
| Set Policy | policy |
Default Action, Block[], Allow[] | Sets your per-tenant resolver policy: block-list or allow-list mode |
| Revoke Agent | revoke |
Agent (handle or /128) |
Fully withdraws the address, PTR, tokens, and key — irreversible |
Attempt a Create on a keyless connection and you get a clear, actionable error — "add your Whisper API key to unlock the control plane" — never a silent no-op. Set Policy also refuses to run with nothing set, since a Zapier Create must change something rather than merely read; leaving Default, Block, and Allow all empty raises the same kind of explicit error.
A concrete Zap: provision on signup, verify on webhook
Zap 1 — "New Stripe customer → register a Whisper agent."
Trigger: Stripe — New Customer. Action: Whisper — Register Agent, Name = {{customer.name}}-bot, Contact Email = {{customer.email}}. Follow with Google Sheets — Create Row to log the returned address, fqdn, and api_key (shown once — this is the only place it will ever appear again).
Zap 2 — "Inbound webhook → verify the caller, branch."
Trigger: Webhooks by Zapier — Catch Hook (your reverse proxy forwards the caller's source /128). Action: Whisper — Verify Agent Identity, Address = {{ip}}. Filter: continue only if is_whisper_agent is true and dane_ok is true. This half needs no key at all — safe to hand to any teammate who only needs the read side.
Try it — with stock tools, and with Whisper
With stock tools (no Zapier, no Whisper software):
# same keyless verdict a Zapier Search step returns
curl -s "https://rdap.whisper.online/verify-identity?ip=2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4" \
| jq '{is_whisper_agent, dane_ok, jws_ok}'
# the RDAP object a Lookup RDAP Record step returns
curl -s https://rdap.whisper.online/ip/2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4 | jq '.status, .events'
# the exact control call a Register Agent Create makes, by hand
curl -sS https://graph.whisper.security/api/query \
-H 'content-type: application/json' \
-H 'X-API-Key: whisper_live_...' \
--data '{"query":"CALL whisper.agents({op:'"'"'register'"'"', args:{label:'"'"'checkout-bot'"'"'}})"}'
With Whisper (the CLI, for comparison — the Zapier app makes the same calls behind typed fields):
whisper verify 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4 # same keyless verdict
whisper create --register --name checkout-bot # same register call
whisper kill --revoke checkout-bot # same revoke call
Both paths land on the identical public endpoints and the identical control verb; Zapier just gives each one a typed step and a Zap history instead of a terminal.
Install it
The app — four searches, three creates, a lib/ Cypher-literal builder, and a full zapier validate test suite — is built entirely on Whisper's public control API, so every step's request and response is a contract you can read before you trust it. It's currently in Zapier's App Directory review; until it clears, you can drive the same control-plane calls directly against the API — see the control plane reference.
Get a key for the control-plane half at whisper.online/platform; the keyless Searches need nothing beyond a running Zap.
Next
- n8n — the same two-tier design as a self-hostable workflow node
- Verify an agent — the full seven-proof keyless verification model behind every Search