A collection of PostHog skills for enhancing AI-assisted workflows. Add this repo as a Claude Code plugin marketplace to get access to all PostHog skills: Then install individual plugins: Or browse available plugins: Copy any skill directory to .claude/skills/ in your project: Any directory under skills/ that contains a .claude-plugin/plugin.json is automatically discovered and added to the market
Add this skill
npx mdskills install PostHog/investigating-replay@PostHog? Sign in with GitHub to claim this listing.Comprehensive session replay investigation workflow with parallel queries, error correlation, and AI-powered summarization.
1---2name: investigating-replay3description: >4 Investigates a session recording by gathering metadata, person profile,5 same-session events, and linked error tracking issues in one pass.6 Use when a user provides a recording or session ID and wants to understand7 what happened — who the user was, what they did, what errors occurred,8 and whether there are related error tracking issues. Replaces the manual9 chain of session-recording-get, persons-retrieve, execute-sql, and10 query-error-tracking-issues-list.11---1213# Investigating a session recording1415When a user asks "what happened in this session?" or provides a recording/session ID16to investigate, gather all relevant context in parallel rather than making them17ask for each piece.1819## Available tools2021| Tool | Purpose |22| ------------------------------------------ | -------------------------------------------------------- |23| `posthog:session-recording-get` | Recording metadata (duration, counts, status) |24| `posthog:persons-retrieve` | Person profile (properties, distinct IDs) |25| `posthog:execute-sql` | Query events, errors, and page views in session |26| `posthog:query-error-tracking-issues-list` | Find error tracking issues linked to the session |27| `posthog:vision-observations-list` | Check for an existing Replay Vision AI summary |28| `posthog:vision-scanners-list` | Find summarizer scanners (`scanner_type=summarizer`) |29| `posthog:vision-scanners-scan-session` | Run a summarizer scanner on the session (slow, optional) |30| `posthog:vision-scanners-create` | Create a temporary summarizer scanner (ask first) |31| `posthog:vision-scanners-delete` | Delete a temporary scanner after summarizing |3233## Workflow3435### Step 1 — Get recording metadata and person profile3637Start with the recording to get metadata and the person's distinct ID:3839```json40posthog:session-recording-get41{42 "id": "<recording_id>"43}44```4546The response includes `distinct_id`, `person`, duration, interaction counts,47console error counts, and viewing status. Use the `distinct_id` to fetch48the full person profile:4950```json51posthog:persons-retrieve52{53 "id": "<person_uuid_from_recording>"54}55```5657### Step 2 — Query same-session events5859Get the timeline of what the user did during the session:6061```sql62posthog:execute-sql63SELECT64 timestamp,65 event,66 properties.$current_url AS url,67 properties.$browser AS browser,68 properties.$os AS os,69 properties.$device_type AS device_type,70 properties.$screen_width AS screen_width71FROM events72WHERE $session_id = '<session_id>'73ORDER BY timestamp ASC74LIMIT 20075```7677For sessions with many events, focus on the most informative ones:7879```sql80posthog:execute-sql81SELECT82 timestamp,83 event,84 properties.$current_url AS url,85 if(event = '$exception', properties.$exception_message, null) AS exception_message,86 if(event = '$exception', properties.$exception_type, null) AS exception_type87FROM events88WHERE $session_id = '<session_id>'89 AND event IN ('$pageview', '$pageleave', '$autocapture', '$exception', '$rageclick')90ORDER BY timestamp ASC91LIMIT 10092```9394### Step 3 — Check for linked error tracking issues9596If the recording has console errors or exceptions, find related error tracking issues:9798```sql99posthog:execute-sql100SELECT DISTINCT101 properties.$exception_fingerprint AS fingerprint,102 properties.$exception_type AS type,103 properties.$exception_message AS message,104 count() AS occurrences105FROM events106WHERE $session_id = '<session_id>'107 AND event = '$exception'108GROUP BY fingerprint, type, message109ORDER BY occurrences DESC110LIMIT 10111```112113If fingerprints are found, search for the corresponding error tracking issues114to provide links and status:115116```json117posthog:query-error-tracking-issues-list118{119 "searchQuery": "<exception_type or message>"120}121```122123### Step 4 — Synthesize the investigation124125Present the findings as a coherent narrative:1261271. **Who** — person properties (name, email, country, plan, etc.)1282. **What** — sequence of pages visited and key actions taken1293. **Problems** — exceptions, console errors, rage clicks, and their frequency1304. **Related issues** — linked error tracking issues with their status (active/resolved)1315. **Context** — session duration, device/browser, activity score132133### Optional: AI summary via Replay Vision134135If the user wants a deeper analysis without reading through events manually,136offer a Replay Vision summary. Follow "check-then-scan" — don't scan blindly,137a scanner can only observe a given session once.1381391. **Check for an existing summary.** A scheduled scanner may already have one:140141 ```json142 posthog:vision-observations-list143 {144 "session_id": "<session_id>"145 }146 ```147148 Look for an observation where `scanner_snapshot.scanner_type` is `summarizer`149 and `status` is `succeeded`. If found, read `scanner_result.model_output`150 (`title`, `summary`, `intent`, `outcome`, `friction_points`, `keywords`) — done,151 no new scan needed.1521532. **Find a summarizer scanner** if none exists yet:154155 ```json156 posthog:vision-scanners-list157 {158 "scanner_type": "summarizer"159 }160 ```161162 - Exactly one → use it.163 - More than one → show the user the scanners (name + prompt) and ask which to use.164 - None → no summarizer scanner exists. See165 **No summarizer scanner? Run a temporary one** below.1661673. **Scan the session** with the chosen scanner. Warn this is async and takes168 several minutes (rasterize + LLM):169170 ```json171 posthog:vision-scanners-scan-session172 {173 "id": "<scanner_id>",174 "session_id": "<session_id>"175 }176 ```1771784. **Retrieve the result** by polling `vision-observations-list` (step 1) until179 the new observation reaches `succeeded`.180181### No summarizer scanner? Run a temporary one182183If the project has no summarizer scanner, you can still produce a one-off summary184with a throwaway scanner — but **ask the user's permission before creating anything**.1851861. **Ask permission** to create a temporary summarizer scanner just to summarize187 this one session.1881892. **Create it disabled** so it never sweeps on a schedule — a disabled scanner190 only runs when you trigger it on demand, so it won't touch other sessions or191 burn quota in the background:192193 ```json194 posthog:vision-scanners-create195 {196 "name": "Temporary on-demand summary",197 "scanner_type": "summarizer",198 "scanner_config": {199 "prompt": "Summarize what the user was trying to do, whether they succeeded, and any friction they hit."200 },201 "query": { "kind": "RecordingsQuery" },202 "model": "gemini-3-flash-preview",203 "enabled": false204 }205 ```2062073. **Scan this session on demand** with the new scanner, then poll for the result:208209 ```json210 posthog:vision-scanners-scan-session211 {212 "id": "<new_scanner_id>",213 "session_id": "<session_id>"214 }215 ```216217 Poll `vision-observations-list` until the observation reaches `succeeded` and218 read `scanner_result.model_output`.2192204. **Ask whether to keep or delete the scanner.** Once you have the observation,221 ask the user if they want to keep the temporary scanner or delete it with222 `vision-scanners-delete`. Deleting is safe: the summary you just read is also223 emitted as an event that persists after the scanner is gone, so cleaning up the224 temporary scanner does not lose the result.225226## Tips227228- Run steps 1-3 in parallel when possible — they're independent queries.229- If the recording has very few events, the session was likely very short.230 Note this rather than suggesting something is broken.231- Console error count from the recording metadata is a good signal for whether232 to dig into exceptions. If it's 0, skip step 3.233- The `start_url` from the recording tells you where the user's journey began —234 use this to frame the narrative.235- If `person` is null on the recording, the user was anonymous.236 Person properties won't be available, but events still are.237
Full transparency — inspect the skill content before installing.