Creating scanners

Replay Vision is in closed beta

Not yet available to everyone – join the waitlist to get updates.

A scanner is made up of four things you author:

  1. A prompt describing what to look for.
  2. A scanner type that determines the output shape – see scanner types.
  3. Recording filters that select which sessions the scanner applies to.
  4. A sampling rate that controls how many matching sessions get scanned.

Start from a template

When you click New scanner you land on the templates picker. The built-in templates cover the most common shapes and are a useful starting point even when your real scanner ends up looking quite different.

The scanner templates picker with the five built-in templates and the create-from-scratch option

The shipping templates are:

TemplateTypeWhat it does
Dead endsMonitorFlag sessions where the user appears stuck with no obvious next action
Session summarySummarizerShort narrative of what the user did
User intentClassifierTag each session with the likely intent (browsing, purchasing, support…)
Frustration scoreScorerNumeric score for how frustrated the user appeared
Session outcomeClassifierTag what happened: task completed, abandoned, errored, etc.
Create from scratchBlank scanner – pick a type yourself

Picking a template just pre-fills the form. You can change anything before saving.

Writing the prompt

This is the single most important thing you'll do. A good prompt is concrete, narrow, and tells the model what to do when it's unsure.

Be concrete, not speculative

The model is good at describing what it sees. It's much less good at guessing intent or emotion from sparse evidence. Anchor the prompt in observable behavior.

✅ "Answer yes if the user scrolls a page for more than 10 seconds without clicking anything and then leaves."

❌ "Answer yes if the user feels confused."

Confusion isn't observable; rage clicks, repeated retries, and dead-end navigation are. Spell those out.

Tell it how to handle uncertainty

When the model is handed an ambiguous session, its default is to make something up. Preempt that by writing the uncertain branch into the prompt.

✅ "If there isn't enough evidence to tell, answer no."

✅ "If the session is too short to judge, tag it unclear."

Cite specific moments in reasoning

Ask for citations in the reasoning, so the result is auditable. The model is already prompted to do this, but it helps to remind it when results are vague.

✅ "Explain your verdict and cite the specific moments in the recording that drove it."

Tune iteratively against real recordings

A prompt that reads beautifully on its own can still misfire. The fastest feedback loop:

  1. Author the scanner.
  2. Run it on-demand against 5–10 recordings you already understand.
  3. Open the observations and read the reasoning + citations.
  4. Adjust the prompt where the model misread something obvious.
  5. Scan another batch of recordings and repeat until the results look right.

Hold off on the automatic background sweep until you trust the scanner's on-demand results – every sweep observation counts against your monthly quota, and a poorly tuned scanner can burn through it fast on results you'd throw away anyway.

Drafting prompts with PostHog AI

Inside the scanner editor, you can ask PostHog AI to draft a prompt by describing what you want in natural language. It picks a scanner type, drafts the prompt, and fills it into the form for you to edit.

The scanner editor with the PostHog AI panel open, ready to draft the scanner prompt

Type-specific configuration

Each scanner type has a few extra knobs. The full reference is on the scanner types page; the highlights:

  • Classifier – define your tag vocabulary, choose whether multiple tags per session are allowed, and whether the model can invent tags outside the vocabulary.
  • Scorer – set the numeric scale (min, max) and an optional label describing what the scale means.
  • Summarizer – pick a summary length (short / medium / long).
  • Monitor – choose whether the model can return inconclusive rather than forcing a yes/no answer.

Filters: scoping the scanner

Recording filters use the same query builder as the rest of Session Replay. You can filter by:

  • Person properties (e.g. plan tier, signup date)
  • Session properties (duration, page count, country)
  • Cohorts
  • Events the session contains

A scanner with no filters matches every eligible session in your project. A scanner with narrow filters – e.g. "sessions on /checkout longer than 30 seconds for users on the trial plan" – is much cheaper, much faster to iterate on, and usually more useful.

A good default discipline: start with a narrow filter while you're tuning the prompt, then widen the filter once you trust the results.

Sampling rate: controlling volume

The sampling rate (0–100%) is applied after the filters match. A scanner with filter "sessions over 30 seconds" and sampling 25% scans roughly one in four of those sessions.

The scanner editor shows a per-month estimate of how many observations the scanner will produce, based on your project's recent recording volume, the filters you've set, and the sampling rate. Use this to size the scanner against your quota before saving.

The triggers step of the scanner editor: sampling rate, recording filters, and the estimated per-month impact against the remaining quota

If the estimate looks too high, you have two knobs:

  • Narrow the filters.
  • Lower the sampling rate.

Enabling and disabling

Scanners are enabled by default when you save. Once enabled, a scanner sweeps for new matching sessions every few minutes.

Toggling a scanner to disabled stops the background sweep. On-demand triggers (from the player or via MCP) still work on a disabled scanner – disabling only affects the automatic schedule.

To stop a scanner entirely, delete it. Deleting a scanner also removes all of its observations from the Observations tab. The $recording_observed events the scanner produced are ordinary PostHog events in your project's event stream and aren't affected – they stay queryable.

Community questions

Was this page useful?

Questions about this page? or post a community question.