Whisper · Docs
Containers & cloud

Browserbase

A cloud browser is a proxy problem in disguise: it launches from someone else's datacenter, on someone else's IPv4 pool, and every site it touches sees a shared, anonymous exit.

No identity, no accountability, nothing to hand a downstream API that expects a stable address; bot-detection flags the pool on sight, and when something goes wrong there's no address to point at. Point Browserbase's external-proxy option at Whisper instead and the browser leaves from your agent's own routable, DNSSEC-signed, RDAP-documented IPv6 /128 — the same identity it uses everywhere else, provable by anyone with dig -x and no key.

This page is the BYOP (Bring-Your-Own-Proxy) recipe: how Browserbase's proxies field maps onto the Whisper egress, the exact wire mechanics, and a runnable two-tier example.

Why this is worth doing

The mechanism: BYOP is just HTTP CONNECT with Basic auth

Browserbase's sessions.create accepts a proxies array. For an external proxy, Browserbase's browser issues an HTTP CONNECT to your server for every outbound TCP stream and authenticates with a Proxy-Authorization: Basic <base64(username:password)> header — RFC 7617 Basic auth, carried over the RFC 9110 §9.3.6 CONNECT method. That's it — no proprietary SDK on the wire, just a standard forward-proxy handshake:

CONNECT v6.ident.me:443 HTTP/1.1
Host: v6.ident.me:443
Proxy-Authorization: Basic dzp3aGlzcGVyX2VncmVzc19iZWFyZXI...

Whisper's egress tier (connect.whisper.online:443) speaks exactly this: username w, password = the agent's egress bearer (issued at register/connect time), and it source-binds every accepted stream to the agent's /128 via IP_FREEBIND + AnyIP over 2a04:2a01::/32 before it ever touches the target. Browserbase validates the proxy at sessions.create, not mid-run — a bad bearer fails immediately with a clear error, not a silent hang three requests in.

const session = await bb.sessions.create({
  projectId,
  proxies: [{
    type: "external",
    server: "http://connect.whisper.online:443",
    username: "w",
    password: process.env.WHISPER_PROXY_PASS, // the agent's egress bearer
  }],
});
const browser = await chromium.connectOverCDP(session.connectUrl);

External proxies on Browserbase are a paid-plan feature — on the free tier, sessions.create with a non-empty proxies array returns 402 Payment Required. This is a Browserbase account gate, not a Whisper one: the keyless verify tier below works on any Browserbase plan, or with no Browserbase account at all.

With stock tools

Everything Whisper emits here is a standard record — you can drive the whole loop with dig, curl, and openssl, no Whisper software involved.

Prove the demo agent's address is a real, delegated, DNSSEC-signed identity:

# Forward: name -> address, DNSSEC-validated
dig +dnssec AAAA acef2002a323d40d4.demo.agents.whisper.online

# Reverse: address -> name (the PTR Whisper synthesizes for every /128 it allocates)
dig -x 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4

# RDAP: the IP-anchored assignment document (RFC 7482/9083) — who holds this /128, since when
curl -s https://rdap.whisper.online/ip/2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4 | jq .

Confirm the TLS identity presented on that address is bound to it (DANE, RFC 6698):

kdig +short TLSA _443._tcp.acef2002a323d40d4.demo.agents.whisper.online
# 3 1 1 b653a4ef...fcb82d1d

openssl s_client -connect '[2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4]:443' \
  -servername acef2002a323d40d4.demo.agents.whisper.online < /dev/null 2>/dev/null \
  | openssl x509 -noout -pubkey \
  | openssl pkey -pubin -outform der | openssl sha256
# compare the hash against the TLSA record above

Drive Browserbase's proxy manually — no Whisper SDK, plain curl through the CONNECT tunnel to sanity-check the credential before wiring it into Playwright:

curl -v -x http://w:$WHISPER_PROXY_PASS@connect.whisper.online:443 \
  https://v6.ident.me/
# -> the agent's own /128, printed back by the echo service

With Whisper

The whisper-examples/browserbase recipe wraps exactly this into a two-tier script — whisper-edge for the keyless half, the Browserbase JS SDK + Playwright for the keyed half.

Tier 1 — keyless verify (no key, no Browserbase account needed):

node index.mjs verify 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4
# { "address": "2a04:2a01:...", "is_whisper_agent": true, "rdap": { ... } }

Tier 2 — keyed egress (needs a Browserbase key + a provisioned agent):

# provision an agent + egress credential, if you don't have one yet
whisper create my-browser-agent
# -> address: 2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4
# -> egress bearer printed once; store it, never log it

export BROWSERBASE_API_KEY=bb_...
export BROWSERBASE_PROJECT_ID=...
export WHISPER_PROXY_PASS=...          # the egress bearer from `whisper create`
export WHISPER_AGENT_128=2a04:2a01:eb5a:ca74:cef2:2a:323d:40d4

node index.mjs
# { "tier": "egress", "session": "...", "seen_ip": "2a04:2a01:...",
#   "is_whisper_agent": true, "expected": "2a04:2a01:...", "matches_agent_address": true }

Same provisioning call, over the control plane directly:

CALL whisper.agents({op:'register', args:{label:'my-browser-agent'}})
CALL whisper.agents({op:'connect', args:{agent:'my-browser-agent', tier:'socks5'}})
  -> { http_proxy, connection_string, dns, doh_url }

http_proxy is exactly the server/username/password triple Browserbase's proxies array expects — copy it in directly. The example script closes the loop itself: after the browser loads the IPv6 echo page, it calls verify(seen_ip) from whisper-edge and asserts the observed address is both a real Whisper agent and the specific /128 you expected — proving, end to end, that the cloud browser's traffic left from your agent's identity, not a shared pool.

Where this fits

Browserbase is one BYOP consumer of the same egress tier that backs every Whisper connect path — see Connect for the full tier ladder (routed WireGuard, SOCKS5/HTTP egress, DoH-only). If you'd rather not hold an egress bearer in your automation at all, the forward gateway offers a single stateless fetch-style endpoint that sources from your agent's /128 without a persistent proxy connection — a good fit for one-shot page fetches instead of a full interactive browser session.

Next

Continue with Connect for the full egress tier reference, or The forward gateway for a proxy-less alternative.