It's local, it's free. Forever.

Page API for developers

When someone records a bug on your site with the Bugcap extension, your page can attach context that a video and logs can't show: who the user is, which release they're on, and what your app thinks is happening. Bugcap exposes a small window.bugcap object on every page for this. There's nothing to install on your side.

Example

// Safe to call on every page load; it does nothing unless Bugcap is installed.
window.bugcap?.setUser({ id: "u_123", email: "[email protected]", plan: "pro" });
window.bugcap?.setContext("release", "2026.10.2");
window.bugcap?.setContext("featureFlags", { newCheckout: true });

// Shows up as a step in the report, synced to the video.
window.bugcap?.track("Checkout started", { items: 3 });

// Adds a marker on the video timeline.
window.bugcap?.mark("Payment form froze here");

Methods

Timing

The API is defined before your scripts run, so you can call it straight away. Calls are kept in the page and only attached to a report if the user records one, so it's safe to call on every page load. The extension can also be installed after your page has loaded, so for code that runs once at startup you can wait for the bugcap:ready event as well:

window.addEventListener("bugcap:ready", () => {
  window.bugcap.setUser({ id: currentUser.id });
});

Privacy

Values are truncated to 500 characters. Keys that look sensitive, such as password, token, secret or session, are replaced with [masked], and anything that looks like a card number is masked too. Don't pass data your users wouldn't expect a bug report to contain. See the privacy policy for everything a report captures.

Masking fields

Steps record what was typed or chosen in form fields, so a developer can reproduce the bug. Password, email, phone, card and one-time-code fields, and fields whose name or label looks sensitive, are always masked. To mask anything else, such as a notes field or a customer panel, add data-bugcap-mask (or the bugcap-mask class) to the field or any element around it:

<input name="memo" data-bugcap-mask />

<section data-bugcap-mask>
  <!-- Every field and message in here is masked. -->
</section>

Steps in a masked area still say which field was used, but its value shows as (masked). Clicked text and messages shown inside it aren't recorded either; those steps name the element by its role and selector instead.

Better step names

Steps name elements by their accessible label, so buttons and fields with visible text, aria-label or a <label> read best. If you use data-testid, data-test, data-cy or data-qa, the step's selector uses it, which makes it easy to turn a report into an automated test.

Reading reports with AI

Every share link has a plain-text Markdown version: add /report.md to the link. It has the title, the AI summary, expected and actual behavior, reproduction steps, the timeline of steps, console errors and failed requests, the narration transcript and annotations, and links to JPEG screenshots of the key moments. Paste the link into an AI assistant or coding agent, or fetch it from a script:

curl https://bugcap.io/s/abc123/report.md

Share pages also advertise it with <link rel="alternate" type="text/markdown">, so tools that read the page can find it. Like the share page, it's available to anyone with the link, and masked values stay masked.