Co-browsing

The support tool of the future.

Embed Esper in your web app and help lives one click away. Your team, human or AI, sees the user's screen of your app and the errors behind it. Nothing else, with their consent, masked by default, on servers you run.

In development · coming in a future release
Co-browsing

See what they see. Fix it together.

A live view of the user's page, a pointer that shows them where to click, and control only if they hand it over. It feels like standing at their desk, without asking anyone to share a screen.

acme.com/settings/billingGet help
BillingAcme Inc. · workspace
We couldn't charge your card. Update your payment method to keep Pro.
Card on file•••• 4242Masked
PlanPro · monthly
Next invoiceOct 1 · €29.00
View invoicesUpdate card

Share this page with Sara from Acme support?

She'll see this app and nothing else. Nothing is shared until you say yes, and you can stop at any time.

Not nowShare this page
Sara can see this pageMasked fields stay hiddenEnd sharing

Help lives in your product

Add the SDK to your web app and wire it to your own help button. Your users never install anything, never read out a code, never join a meeting link.

A page, not a screen

Your team sees the user's view of your app and nothing else. Other tabs, other windows and the desktop behind the browser cannot appear, by construction.

The console comes to you

Console output, errors and failing requests appear live beside the page. Nobody has to ask a customer to open the developer tools.

Consent runs the session

Nothing is shared until the user accepts a prompt that names who is asking. A visible indicator stays on for the whole session, and one click ends it.

Rewind, by invitation

Users can include the last few minutes when they ask for help. Until they tick that box, it lives in their browser's memory and nowhere else.

Yours, end to end

The SDK connects to a relay you host, and every session is encrypted end to end. The relay forwards ciphertext it cannot read. There is no Esper cloud.

How it works

From stuck to helped in one click.

No installs, no meeting links, no codes read over the phone. The whole path runs inside your product, on your servers.

  1. Run the relay

    One binary on your server, next to the broker you may already run. No state, no database, and it cannot read a session.

  2. Install the SDK

    One npm package in your web app, pointed at your relay. Your support admins pair like any Esper device and get co-browsing scopes.

  3. A user asks for help

    They click your own help button. Nothing is captured yet: the request just appears for your team, with whatever context you attach.

  4. They say yes

    A prompt names the person asking to look. Decline, and nothing was ever shared. Accept, and a visible indicator switches on.

  5. Your team helps

    They see the user's page as it changes and the errors behind it, and point at what to click next. Taking control is a separate question the user answers on screen.

Scope

They share a page. Not their life.

Screen sharing hands over everything on a monitor. Co-browsing is scoped to your app by construction. The rest of the user's machine is not dimmed or cropped out, it is simply not there.

What your team sees

  • Their live view of your app, as it changes
  • Console output, errors and failing requests, live
  • The last few minutes, only if they tick the box when asking
  • Where your agent should look: pointing and highlights
  • Fields you have chosen to unmask
  • Context you attach: page, version, signed-in user

What it can never see

  • Other tabs, other windows, the desktop behind the browser
  • Masked fields, which never leave the user's page
  • Passwords and payment fields, which cannot be unmasked
  • Auth headers and cookies, redacted before anything leaves
  • Sessions of anyone who never asked for help
  • Anything before the user consents, or after they end it
Diagnostics

Full context. Zero recording.

The logs, the errors, the failing requests, the moments before: everything a session-replay suite gives support, scoped to one session one user asked for. People who never ask for help never send a byte.

Consolelive · this session only

12:04:31 · payment form mounted

12:04:52 · POST /api/charge → 402

12:04:52 · Uncaught TypeError: card.expiry is undefined

at validateCard (billing.js:214)

12:05:08 · Authorization: [redacted]

Shared with this sessionNothing is stored

Live devtools, agent side

Console output, uncaught errors with stacks, failing requests and performance appear beside the page while your team helps. Auth headers and cookies are redacted before anything leaves the browser; request bodies travel only for routes you allow.

Errors arrive with the request

Attach the page's recent errors to the help request itself, so your team triages before anyone joins. A crash that explains itself may never need a session at all.

The last few minutes, by choice

The SDK can keep a short rewind buffer in the user's browser memory, never anywhere else. When they ask for help, one checkbox includes it. Unticked, not a byte of it ever leaves the page.

AI support

Put an agent in the chair.

Co-browsing speaks MCP like the rest of Esper, so the support seat can hold a person, an AI, or an AI that knows when to hand over.

  • First response in seconds, and a person one click away.
  • It guides on the page. Walking a user through pasting an API key while the key stays masked. The machine helping never reads the secret.
  • Any model, no blessed vendor. The same scoped grants a human admin holds.
Claudeover MCPSupport seat
Sees the page and the consoleview · inspect
Points at the next clickpoint
Reads a masked fieldnot in the mirror
Takes controlasks the user first
Named as an AI to the userEvery action audited
Data protection

Built for GDPR.

Session tooling is where privacy reviews stall: always-on recording, stored replays, a vendor in the data path. This one was designed so there is almost nothing to review.

ConsentArt. 7Nothing captured until a named, revocable yes. On demand is the architecture: no always-on mode exists.
Data minimisationArt. 5Inputs masked unless you unmask them; secrets redacted before anything leaves the browser.
Storage limitationArt. 5Live sessions, a stateless relay, no recordings. A subject access request has nothing to return.
ProcessorsArt. 28Self-hosted: no vendor DPA, no sub-processor list, and Esper never appears in your privacy notice.
TransfersCh. VEverything is end-to-end encrypted on your own servers. Nothing crosses a border.

Compliance is a property of your deployment, not a badge on a tool. Esper's part is leaving almost nothing to review.

Integration

A help button, not a project.

Point the SDK at your relay and wire it to your own UI. Where the button lives, what it says and when it shows is your product's call. Esper handles everything after the click.

terminal
npm install @esper/cobrowse
support.ts
import { esper } from "@esper/cobrowse";
esper.init({
relay: "wss://support.acme.com",
siteKey: "pk_live_…",
});
// your button, wherever it lives
helpButton.onclick = () => esper.requestHelp();

Plain TypeScript

No framework required. The site key is publishable and grants nothing on its own.

One-attribute masking

Hide anything with data-esper-mask. Inputs are masked before you do anything at all.

Verified identity

Greet users by name: your backend signs a short-lived token, and the claim is verified, never taken from client-side code.