Session replay your AI agent sets up and reads

AgentFirstStack Replay is free, open-source session replay that an AI agent sets up and reads. It replaces Hotjar (now Contentsquare), Microsoft Clarity and Fullstory: recordings masked in the visitor's browser, each session as a readable transcript, rage, dead and error clicks, JS errors, heatmaps and surveys. Your agent creates it with one request, serves it from your own domain, asks for consent where the law requires it, and tests the install itself. Choose Clarity or Fullstory if people will watch replays in a dashboard every day, or you need mobile apps or months of history.

Updated

Set it up with one prompt

Recording sessions is a bigger privacy decision than counting visits, so the prompt keeps the strict default masking and asks for consent in the EEA, the UK and Switzerland.

Paste this into Claude Code, Cursor or Codex

Add session replay to this project with AgentFirstStack Replay. It's free, open-source session replay built for agents, masked in the visitor's browser by default, and you can do the setup yourself: there is no signup form. 1. Read https://agentfirststack.com/llms.txt and https://replay.agentfirststack.com/llms.txt. 2. If this project's .env already has AGENTFIRSTSTACK_API_KEY, use it and read AGENTFIRSTSTACK.md. Otherwise get a key: curl -X POST https://agentfirststack.com/v1/signup, and save api_key in .env as AGENTFIRSTSTACK_API_KEY and in the production secrets. 3. Create a replay site for the production domain with require_consent "eea". If the site runs AgentFirstStack analytics, link it with analytics_site_id, so the analytics tracker loads the recorder; otherwise add the snippet from the install answer to the head of every page. 4. Serve it from the site's own domain. If the project has no first-party domain yet, create one (POST https://agentfirststack.com/v1/first-party-domains with a neutral subdomain such as edge.<domain>): add its one CNAME if you can change the DNS, otherwise give me the record and use the path proxy from the install answer meanwhile, with the proxy key kept server-side. 5. Keep mask_mode strict. Unmask only interface text (nav, buttons, links, headings, labels), and block chat widgets and account details with block_selectors. 6. Deploy, open the homepage with ?afsr=1 and click through the main pages, then run verify and fix what it reports. Run GET https://agentfirststack.com/v1/setup?services=replay until the replay rows pass. 7. If the site runs Hotjar, Contentsquare, Microsoft Clarity or Fullstory, tell me, copy its masking rules into the replay site's selectors, and leave it installed: recordings can't be moved. 8. Write the replay site id and the env var name (never the key) in AGENTFIRSTSTACK.md, and create a claim link for me with POST https://agentfirststack.com/v1/claim-link. Tell me what you set up, what verify returned, how to turn replay off, and give me the claim link.

This is the replay part of the full setup. For analytics, tags, an inbox and replay together, use the full setup prompt.

What your agent does

  1. Gets a key with POST https://agentfirststack.com/v1/signup, or reuses the one in .env. One key works for every service.
  2. Creates the replay site with POST https://replay.agentfirststack.com/v1/sites (MCP replay_create_replay_site), linked to the analytics site. The analytics tracker then loads the recorder by itself: nothing to paste. Without analytics, the answer has a <script defer> tag for the head.
  3. Serves it first-party. A first-party domain (POST /v1/first-party-domains {"hostname":"edge.example.com"}, one CNAME to fp.agentfirststack.com) serves replay at /_r/* next to analytics and tags, and the tracker loaded from it loads the recorder from it too. Where the DNS can't change, a path proxy forwards /_r/* with the site's proxy key. Either way the recorder doesn't load from a third-party host, which is what ad blockers block.
  4. Sets the privacy rules with PATCH /v1/sites/:id: unmask_selectors for interface text, block_selectors for what must never be recorded, exclude_paths for whole pages, require_consent and the consent source.
  5. Tests it. It opens a page with ?afsr=1, which forces a recording even in a headless browser, then calls POST /v1/sites/:id/verify (MCP replay_verify_install). Verify fetches the live homepage, finds the loader or the linked tracker in a real script tag, checks the Content-Security-Policy, proves the domain, and reports sessions received, chunks refused and whether labels are all masked.
  6. Reads the sessions: the most frustrated first, one as a transcript, then patterns across many.
  7. Hands over a claim link (POST /v1/claim-link), so you can see the project in a dashboard with Google sign-in.
R=https://replay.agentfirststack.com
H="Authorization: Bearer $AGENTFIRSTSTACK_API_KEY"

curl -s -X POST $R/v1/sites -H "$H" -H 'content-type: application/json' \
  -d '{"domain":"example.com","analytics_site_id":"site_...","require_consent":"eea"}'
curl -s -X PATCH $R/v1/sites/$RSITE -H "$H" -H 'content-type: application/json' \
  -d '{"unmask_selectors":["nav","button","a","h1","h2","label"],"block_selectors":["#chat-widget"]}'
# after one visit to https://example.com/?afsr=1
curl -s -X POST $R/v1/sites/$RSITE/verify -H "$H"
curl -s "$R/v1/sites/$RSITE/sessions?sort=frustration&signal=rage_click" -H "$H"
curl -s "$R/v1/sites/$RSITE/sessions/$SESSION/transcript" -H "$H"
curl -s "$R/v1/sites/$RSITE/summary?page=/checkout*&period=7d" -H "$H"

A transcript is one line per step, with the element's label as recorded and a CSS selector the agent can try on the live page:

[00:00.0] page "/pricing" · load · from "google.com" · stayed 15s · saw 64% of the page
[00:05.1] click button "Start trial" {"#plans > div:nth-of-type(2) > button.cta"}
[00:07.9] typed into input[type=email] "Email" name="email" (value masked)
[00:09.3] click x4 in 0.8s button "Pay" {"#checkout button.pay"}  [RAGE DEAD ERROR-CLICK]
[00:09.5] JS error "TypeError: Cannot read properties of undefined (reading 'id')" after click on {"#checkout button.pay"}  [ERROR-CLICK]
[00:15.0] page "/signup" · push · from "/pricing" · stayed 2s · saw 30% of the page  [QUICK-BACK]

Recorded page text comes back marked untrusted, so the agent treats it as data and never as instructions.

What you get

  • Recording: a loader of about 1.7 KB gzipped decides whether the tab is recorded, then loads the recorder (rrweb, about 32 KB gzipped) after the page's load event. Sampling, excluded paths and IP ranges, and a page API to identify users, tag sessions (plan, A/B variant) and mark named steps.
  • Masking in the browser: strict by default (every text node and text attribute becomes asterisks), or balanced and relaxed. Typed values are masked in every mode; password, payment-card and one-time-code fields can't be unmasked. Query strings are removed and id-like path segments become :id. Canvas and cross-origin iframes aren't captured.
  • Consent: require_consent: "eea" waits for consent only from visitors in the EEA, the UK and Switzerland; consent from afsr('consent', true), Google Consent Mode or an IAB TCF v2 CMP. Browsers that send Global Privacy Control or Do Not Track aren't recorded. No cookies: the session lives in the tab's sessionStorage.
  • Sessions as text: search by page, signal, error, device, country, referrer, user, tag or frustration score; transcripts as text or JSON; summaries across up to 1,000 sessions (top rage-click targets, dead clicks, errors, exit pages, common journeys) with example session ids, worked out without a model; CSV and NDJSON exports and the raw rrweb events.
  • Signals: rage clicks (3 or more within 1 second on one element), dead clicks (nothing changes within 1 second), error clicks (a JS error within 1 second of a click), quick backs, excessive scrolling, JS errors, failed requests if you turn them on, and a frustration score from 0 to 100.
  • Heatmaps: click, scroll and attention maps as data, by element or by page zone, with how many pageviews scrolled far enough to see each element, comparisons with an earlier period, a device or a segment, and plain-sentence findings such as CTAs few people reach. A PNG of the page with the overlay too, for claimed projects.
  • Errors: JS errors grouped by fingerprint with the click that triggered them, the pages and browsers they happen on, and example sessions; failed requests grouped by method, path and status.
  • Surveys and feedback: popovers, embedded surveys and a feedback tab with NPS, CSAT, CES, product-market fit and free-text templates, triggered on load, scroll, exit intent or a rage click. Each answer links to its session, so the agent can read what a detractor did.
  • Analysis: saved segments, metrics over time by page, referrer or tag, funnel drop-offs with what the people who dropped did, and events defined after the fact from clicks already recorded.
  • Signals sent on: linked to an analytics site, rage, dead and error clicks, JS errors, quick backs and excessive scrolls arrive there as events, joined to the visitor. Linked to a tags container, rage and dead clicks, JS errors, failed requests and survey scores go to it as server events: to GA4 under the same name, and to ad platforms only through a conversion you define. Test sessions stay test traffic in both.
  • Workflow: notes, labels and stars on sessions; signed webhooks for survey answers, new errors, sessions entering a segment and signal spikes; share links to a player, for a whole session or a clip.
  • Privacy requests: look up everything stored about one visitor, and delete it by user id, analytics visitor id, session ids or email. The IP address is never stored.

What the setup check verifies

GET https://agentfirststack.com/v1/setup (MCP afs_check_setup) reads what the services have received and lists these rows for replay, per website. It fetches nothing from the site; the replay verify call and the setup test do that.

CheckTitlePasses when
replay.siteReplay records the websiteA replay site exists for the domain and is enabled; the detail names its masking mode
replay.linkedReplay is linked to analyticsThe replay site has an analytics_site_id, so it loads with the tracker and sessions join analytics visits
replay.verifiedReplay's domain is verifiedVerify found the recorder or the linked tracker on the homepage, or the DNS TXT record; until then replay records only a short trial
replay.recordingSessions are being recordedAt least one session has arrived
replay.proxy_keyRecordings through a first-party proxy carry its proxy keyShown only when uploads in the last 7 days came through a path proxy without the right key
replay.consentVisitors from the EU, UK and Switzerland are recorded only after consentA warning when require_consent is off, which is fine if the owner decided so

The setup test (POST /v1/setup/test) runs replay's verify on the live homepage, and its browser plan opens the site with ?afsr=1, so afs_check_test_visit can confirm a test recording arrived. If the tags scan found Hotjar, Clarity, Fullstory or LogRocket on the site, the "other tools" row names it: there's nothing to import, because recordings can't move.

Compared with

Facts about other products as of 7 November 2026, from their own pages.

ToolWhat it is and costsRecordings keptComparison
Hotjar (now Contentsquare)New Hotjar accounts can't be created; new users sign up for Contentsquare (contentsquare.com/hotjar). Free up to 200k monthly sessions with 5% captured as replays (max. 10k), Growth from $39 a month, APIs on Pro and Enterprise only (pricing)1 month on Free, 2 on Growth, up to 24 on Pro and EnterpriseHotjar alternative
Microsoft ClarityFree, with no traffic limits and no sampling (FAQ); its Data Export API allows 10 requests a project a day (docs)30 days; labelled or favorited sessions 9 months (data retention)Clarity alternative, Clarity MCP
FullstoryDigital experience analytics: replay with product analytics, mobile apps as an add-on and warehouse sync as a separate product. FullstoryFree has 30,000 sessions a month for up to 10 users; paid plans are priced on request (pricing)"12 months of data retention" on FullstoryFreeFullstory alternative
AgentFirstStack ReplayFree hosted service with fair-use limits; AGPL-3.0, recorder MIT; set up and read by an agent over REST and MCP14 days hosted; daily heatmap aggregates up to 90 daysThis page

Limits

On the hosted service (the lower number applies until a person claims the project):

  • 5 replay sites per project (2), and one unverified site at a time, which records a trial of 20 sessions a day (10) with strict masking.
  • 200 recorded sessions per site a day (100), each up to 30 minutes and 2 MB.
  • Recordings kept up to 14 days; daily heatmap aggregates up to 90 days.
  • 5 active share links per site (3).
  • Heatmap images for claimed projects only, 10 per site and 30 per project a day.
  • Up to 500 signals a day per site sent on to analytics, and 500 to tags.

Every cap, with what the project has used: GET /v1/usage (MCP replay_get_usage). The full list is on fair-use limits. Need more? Self-host it: pnpm afs init <name> --domain example.com --account <id>, then pnpm afs deploy <name> on your own Cloudflare account, with retention up to 365 days.

When it isn't the right fit

  • Mobile apps. It records websites only. Clarity, Fullstory and Contentsquare have native app SDKs.
  • Every session at high traffic. The hosted service records 200 sessions per site a day. Clarity has no traffic limits.
  • Months of recordings. Hosted recordings are kept 14 days, against Clarity's 30 days and FullstoryFree's 12 months of data retention.
  • A team that watches replays all day. People get a player behind share links and a Watch button in the dashboard, but the product is built for an agent reading text. Contentsquare, Clarity and Fullstory are built for people watching and have fuller interfaces for it.
  • Model-written summaries. Summaries, findings and survey themes are computed without a model; your agent does the interpreting. Clarity's Copilot and Fullstory's StoryAI write summaries for you.
  • Warehouse sync and enterprise controls. There's no sync to Snowflake or BigQuery (exports are CSV, NDJSON and raw events), and no SAML single sign-on.
  • A full consent platform. The tags consent banner gates the container's tags, Consent Mode, replay and the analytics tracker, but it doesn't scan for cookies or block scripts loaded outside the container.

FAQ

What is session replay?

Session replay records what visitors do on a website (pages, clicks, scrolling, typing into fields, errors) so you can see where they get stuck. AgentFirstStack Replay records the page's changes with rrweb, not video, and also returns each session as a text transcript an agent can read.

Is AgentFirstStack Replay free?

Yes. The hosted service is free within fair-use limits: 5 replay sites per project, 200 recorded sessions per site a day and recordings kept 14 days. The service is open source under AGPL-3.0, the recorder is MIT, and you can self-host it on Cloudflare with your own limits.

What does it record, and what stays masked?

By default every text node and every typed value is masked in the visitor's browser before anything is sent. Your agent unmasks interface text such as navigation, buttons and headings. A typed value shows only if the page marks that field with data-afsr-unmask, and never for passwords, payment cards or one-time codes. Query strings are removed from URLs and the IP address is never stored.

Does it ask visitors for consent?

With require_consent set to eea, visitors from the EU, Iceland, Liechtenstein, Norway, the UK and Switzerland are recorded only after consent; everyone else is recorded at once. Consent can come from your own banner calling afsr('consent', true), Google Consent Mode, an IAB TCF v2 CMP, or the AgentFirstStack tags consent banner. The recorder sets no cookies.

Can a person watch the recordings?

Yes. Your agent can create an expiring share link that opens one session, or a clip of it, in a player. Once you claim the project, the dashboard lists the most frustrated sessions first, with their transcripts and JS errors, and a Watch button that opens the player.

Does it record mobile apps?

No. It records websites only, in the browser. Microsoft Clarity, Fullstory and Contentsquare have SDKs for native apps.

Product names belong to their owners. AgentFirstStack isn't affiliated with Contentsquare, Hotjar, Microsoft or Fullstory.