Whisper · Docs
Automation

Pipedream

Wiring agent identity into a no-code workflow usually means a generic HTTP node, a hand-built JSON body, and a prayer that you got the escaping right.

One unescaped quote in an agent label and your Cypher call breaks; one leaked bearer in a step export and it's in your run history forever. Whisper's Pipedream app removes all of that: a real registered app with typed props, a Cypher-literal builder that can't be broken by user input, and a response decoder that turns the control-plane envelope into a plain array of records — 12 actions, split into a keyless tier anyone can drag onto a canvas and a keyed control tier that provisions and governs your fleet.

Two tiers, one app

The whisper app follows the same Postel's-Law shape as every Whisper integration (see the integration standard): the credential is what unlocks the second tier, not a separate product.

The app registers one optional auth field, api_key. Leave it blank and the four keyless actions still work; every keyed action checks for it up front and throws a ConfigurationError — a clear message, not a bare 401 three steps into a workflow — if it's missing.

The 12 actions

# Action Tier Op / endpoint
1 Verify Agent Identity keyless GET /verify-identity?ip=
2 Lookup RDAP Record keyless GET /ip/<addr>
3 Get Transparency Log keyless GET /ip/<addr>/transparency
4 Get Inbound Lookups keyless GET /ip/<addr>/lookups
5 Register Agent control op:register
6 Allocate Identity control op:identity
7 List Agents control op:list
8 Get Agent control op:agent
9 Set Policy control op:policy
10 Get Logs control op:logs
11 Connect Egress control op:connect
12 Revoke Agent control op:revoke

All eight keyed actions carry the same admin:dns (write) or read scope that a matching whisper CLI subcommand carries, and every one is confined to the caller's own tenant — there is no cross-tenant argument to smuggle through args.

Under the hood: one Cypher verb

Every control action is a thin wrapper over a single call: CALL whisper.agents({op:'<op>', args:{…}}), POSTed as {"query": "..."} to https://graph.whisper.security/api/query with the caller's key in X-API-Key — never in the body. This is the exact contract documented in the Graph API reference and implemented once, correctly, in the whisper CLI's reference client.

With stock tools — build and send the same call by hand with curl and jq:

curl -s https://graph.whisper.security/api/query \
  -H "X-API-Key: whisper_live_…" \
  -H 'content-type: application/json' \
  -d '{"query":"CALL whisper.agents({op:'"'"'register'"'"', args:{label:'"'"'scout'"'"'}})"}' \
  | jq '.rows[0].result'

Get the string-escaping wrong — an unescaped ' in a label like O'Brien's bot — and that quote closes the Cypher literal early and the query fails, or worse, is misparsed. Doing this safely by hand means writing your own doubled-quote escaper and a two-shape response decoder (the control endpoint can return either a procedure-row table or a flat {ok,status,result,error} envelope — see the reference for both shapes).

With Whisper — the app does the escaping and decoding for you; the action just takes typed props:

Register Agent
  Name:            scout
  Contact Email:   (optional)
→ $summary: "Registered agent scout at 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4"
→ returns: { agent, address, fqdn, ptr, state, api_key }

That api_key field is the new agent's own credential and is returned once — capture it in the same run (write it to a connected secrets step, not to a public output).

The app's Cypher builder mirrors the CLI's exactly: a string value is single-quoted with ' and \ each doubled (Tim O'Reilly'Tim O''Reilly'), map keys are emitted in sorted order so the wire query is byte-stable, and the response decoder accepts both envelope shapes plus a bare problem object — surfacing detail (or title, or type) verbatim on failure rather than an opaque 500. That's the Robustness Principle (RFC 761) applied to a no-code canvas: conservative in what the action emits on the wire, liberal in what it accepts back.

A worked example: gate a Slack alert on agent identity

Say a workflow ingests inbound webhook traffic and you want to flag anything not coming from a genuine Whisper agent before it reaches a downstream step.

With stock tools (a Pipedream Node code step, no Whisper software):

import { axios } from "@pipedream/platform";

export default defineComponent({
  async run({ steps, $ }) {
    const ip = steps.trigger.event.headers["x-forwarded-for"];
    const r = await axios($, {
      url: "https://rdap.whisper.online/verify-identity",
      params: { ip },
      headers: { Accept: "application/json" },
      validateStatus: () => true,
    });
    if (!r.is_whisper_agent) throw new Error(`${ip} is not a verified Whisper agent`);
    return r;
  },
});

With Whisper — drop in the Verify Agent Identity action (no code, no auth needed), then branch on its is_whisper_agent export directly in the workflow's conditional path — one action, typed output, no hand-rolled HTTP client.

Connect Egress — the one action with secrets in it

op:connect is the odd one out: its result carries live transport secrets (an et_… bearer embedded in http_proxy/connection_string for the socks5/anyip tiers, or a client_private_key for a zero-key WireGuard setup). Because a hosted Pipedream step's output can end up in run history and downstream step data, the action follows the same bearer-hygiene rule as every other Whisper integration: don't wire the raw secret fields into a Slack message, a database row, or anything outside the same run's next HTTP step. If your workflow just needs a routed egress endpoint to hand to an HTTP-request node's proxy setting, that's exactly what this action is for — use it as a proxy config, not a value to persist.

Installing it

The app is contributed as source in PipedreamHQ/pipedream under components/whisper/, the same self-serve model as the Whisper n8n, Make, and Power Platform connectors — no vendor account required to review the code, just Pipedream's own app-integration step before a submitted app goes live in the workspace picker. Once live, search "Whisper" when adding an app to a workflow; the keyless actions need nothing further, and the control actions prompt you to connect an account with your whisper_live_… key.

The key-gated DNS resolver (/dns-query) is intentionally not wrapped here — it's a stateful per-tenant :53/DoH endpoint, not a request/response action. Point your own resolver config at it directly; see DoH.

Next

Graph API — the whisper.agents control verb · Integrations catalog