/investigating-replay
Investigates a session recording by gathering metadata, person profile, same-session events, and linked error tracking issues in one pass. Use when a user provides a recording or session ID and wants to understand what happened — who the user was, what they did, what errors
$ npx -y skills add posthog/posthog --skill investigating-replay --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/investigating-replay
Context preview
The summary Claude sees to decide when to auto-load this skill.
Investigates a session recording by gathering metadata, person profile, same-session events, and linked error tracking issues in one pass. Use when a user provides a recording or session ID and wants to understand what happened — who the user was, what they did, what errors
SKILL.md
investigating-replay.SKILL.mdname: investigating-replay
description: >
Investigates a session recording by gathering metadata, person profile,
same-session events, and linked error tracking issues in one pass.
Use when a user provides a recording or session ID and wants to understand
what happened — who the user was, what they did, what errors occurred,
and whether there are related error tracking issues. Replaces the manual
chain of session-recording-get, persons-retrieve, execute-sql, and
query-error-tracking-issues-list.
Investigating a session recording
When a user asks "what happened in this session?" or provides a recording/session ID to investigate, gather all relevant context in parallel rather than making them ask for each piece.
Available tools
| Tool | Purpose | | ------------------------------------------ | -------------------------------------------------------- | | `posthog:session-recording-get` | Recording metadata (duration, counts, status) | | `posthog:persons-retrieve` | Person profile (properties, distinct IDs) | | `posthog:execute-sql` | Query events, errors, and page views in session | | `posthog:query-error-tracking-issues-list` | Find error tracking issues linked to the session | | `posthog:vision-observations-list` | Check for an existing Replay Vision AI summary | | `posthog:vision-scanners-list` | Find summarizer scanners (`scanner_type=summarizer`) | | `posthog:vision-scanners-scan-session` | Run a summarizer scanner on the session (slow, optional) | | `posthog:vision-scanners-create` | Create a temporary summarizer scanner (ask first) | | `posthog:vision-scanners-delete` | Delete a temporary scanner after summarizing |
Workflow
Step 1 — Get recording metadata and person profile
Start with the recording to get metadata and the person's distinct ID:
posthog:session-recording-get
{
"id": "<recording_id>"
}The response includes `distinct_id`, `person`, duration, interaction counts, console error counts, and viewing status. Use the `distinct_id` to fetch the full person profile:
posthog:persons-retrieve
{
"id": "<person_uuid_from_recording>"
}Step 2 — Query same-session events
Get the timeline of what the user did during the session:
posthog:execute-sql
SELECT
timestamp,
event,
properties.$current_url AS url,
properties.$browser AS browser,
properties.$os AS os,
properties.$device_type AS device_type,
properties.$screen_width AS screen_width
FROM events
WHERE $session_id = '<session_id>'
ORDER BY timestamp ASC
LIMIT 200For sessions with many events, focus on the most informative ones:
posthog:execute-sql
SELECT
timestamp,
event,
properties.$current_url AS url,
if(event = '$exception', properties.$exception_values[1], null) AS exception_message,
if(event = '$exception', properties.$exception_types[1], null) AS exception_type
FROM events
WHERE $session_id = '<session_id>'
AND event IN ('$pageview', '$pageleave', '$autocapture', '$exception', '$rageclick')
ORDER BY timestamp ASC
LIMIT 100Step 3 — Check for linked error tracking issues
If the recording has console errors or exceptions, find related error tracking issues:
posthog:execute-sql
SELECT DISTINCT
properties.$exception_fingerprint AS fingerprint,
properties.$exception_types[1] AS type,
properties.$exception_values[1] AS message,
count() AS occurrences
FROM events
WHERE $session_id = '<session_id>'
AND event = '$exception'
GROUP BY fingerprint, type, message
ORDER BY occurrences DESC
LIMIT 10If fingerprints are found, search for the corresponding error tracking issues to provide links and status:
posthog:query-error-tracking-issues-list
{
"searchQuery": "<exception_type or message>"
}Step 4 — Synthesize the investigation
Present the findings as a coherent narrative:
1. **Who** — person properties (name, email, country, plan, etc.) 2. **What** — sequence of pages visited and key actions taken 3. **Problems** — exceptions, console errors, rage clicks, and their frequency 4. **Related issues** — linked error tracking issues with their status (active/resolved) 5. **Context** — session duration, device/browser, activity score
Optional: AI summary via Replay Vision
If the user wants a deeper analysis without reading through events manually, offer a Replay Vision summary. Follow "check-then-scan" — don't scan blindly, a scanner can only observe a given session once.
1. **Check for an existing summary.** A scheduled scanner may already have one:
posthog:vision-observations-list
{
"session_id": "<session_id>"
}Look for an observation where `scanner_snapshot.scanner_type` is `summarizer` and `status` is `succeeded`. If found, read `scanner_result.model_output` (`title`, `summary`, `intent`, `outcome`, `friction_points`, `keywords`) — done, no new scan needed.
2. **Find a summarizer scanner** if none exists yet:
posthog:vision-scanners-list
{
"scanner_type": "summarizer"
}- Exactly one → use it.
- More than one → show the user the scanners (name + prompt) and ask which to use.
- None → no summarizer scanner exists. See
**No summarizer scanner? Run a temporary one** below.
3. **Scan the session** with the chosen scanner. Warn this is async and takes several minutes (rasterize + LLM):
posthog:vision-scanners-scan-session
{
"id": "<scanner_id>",
"session_id": "<session_id>"
}4. **Retrieve the result** by polling `vision-observations-list` (step 1) until the new observation reaches `succeeded`.
No summarizer scanner? Run a temporary
Read more
name: investigating-replay description: > Investigates a session recording by gathering metadata, person profile, same-session events, and linked error tracking issues in one pass. Use when a user provides a recording or session ID and wants to understand what happened — who the user was, what they did, what errors occurred, and whether there are related error tracking issues. Replaces the manual chain of session-recording-get, persons-retrieve, execute-sql, and query-error-tracking-issues-list.
Investigating a session recording
When a user asks "what happened in this session?" or provides a recording/session ID to investigate, gather all relevant context in parallel rather than making them ask for each piece.
Available tools
| Tool | Purpose | | ------------------------------------------ | -------------------------------------------------------- | | `posthog:session-recording-get` | Recording metadata (duration, counts, status) | | `posthog:persons-retrieve` | Person profile (properties, distinct IDs) | | `posthog:execute-sql` | Query events, errors, and page views in session | | `posthog:query-error-tracking-issues-list` | Find error tracking issues linked to the session | | `posthog:vision-observations-list` | Check for an existing Replay Vision AI summary | | `posthog:vision-scanners-list` | Find summarizer scanners (`scanner_type=summarizer`) | | `posthog:vision-scanners-scan-session` | Run a summarizer scanner on the session (slow, optional) | | `posthog:vision-scanners-create` | Create a temporary summarizer scanner (ask first) | | `posthog:vision-scanners-delete` | Delete a temporary scanner after summarizing |
Workflow
Step 1 — Get recording metadata and person profile
Start with the recording to get metadata and the person's distinct ID:
posthog:session-recording-get
{
"id": "<recording_id>"
}The response includes `distinct_id`, `person`, duration, interaction counts, console error counts, and viewing status. Use the `distinct_id` to fetch the full person profile:
posthog:persons-retrieve
{
"id": "<person_uuid_from_recording>"
}Step 2 — Query same-session events
Get the timeline of what the user did during the session:
posthog:execute-sql
SELECT
timestamp,
event,
properties.$current_url AS url,
properties.$browser AS browser,
properties.$os AS os,
properties.$device_type AS device_type,
properties.$screen_width AS screen_width
FROM events
WHERE $session_id = '<session_id>'
ORDER BY timestamp ASC
LIMIT 200For sessions with many events, focus on the most informative ones:
posthog:execute-sql
SELECT
timestamp,
event,
properties.$current_url AS url,
if(event = '$exception', properties.$exception_values[1], null) AS exception_message,
if(event = '$exception', properties.$exception_types[1], null) AS exception_type
FROM events
WHERE $session_id = '<session_id>'
AND event IN ('$pageview', '$pageleave', '$autocapture', '$exception', '$rageclick')
ORDER BY timestamp ASC
LIMIT 100Step 3 — Check for linked error tracking issues
If the recording has console errors or exceptions, find related error tracking issues:
posthog:execute-sql
SELECT DISTINCT
properties.$exception_fingerprint AS fingerprint,
properties.$exception_types[1] AS type,
properties.$exception_values[1] AS message,
count() AS occurrences
FROM events
WHERE $session_id = '<session_id>'
AND event = '$exception'
GROUP BY fingerprint, type, message
ORDER BY occurrences DESC
LIMIT 10If fingerprints are found, search for the corresponding error tracking issues to provide links and status:
posthog:query-error-tracking-issues-list
{
"searchQuery": "<exception_type or message>"
}Step 4 — Synthesize the investigation
Present the findings as a coherent narrative:
1. **Who** — person properties (name, email, country, plan, etc.) 2. **What** — sequence of pages visited and key actions taken 3. **Problems** — exceptions, console errors, rage clicks, and their frequency 4. **Related issues** — linked error tracking issues with their status (active/resolved) 5. **Context** — session duration, device/browser, activity score
Optional: AI summary via Replay Vision
If the user wants a deeper analysis without reading through events manually, offer a Replay Vision summary. Follow "check-then-scan" — don't scan blindly, a scanner can only observe a given session once.
1. **Check for an existing summary.** A scheduled scanner may already have one:
posthog:vision-observations-list
{
"session_id": "<session_id>"
}Look for an observation where `scanner_snapshot.scanner_type` is `summarizer` and `status` is `succeeded`. If found, read `scanner_result.model_output` (`title`, `summary`, `intent`, `outcome`, `friction_points`, `keywords`) — done, no new scan needed.
2. **Find a summarizer scanner** if none exists yet:
posthog:vision-scanners-list
{
"scanner_type": "summarizer"
}- Exactly one → use it.
- More than one → show the user the scanners (name + prompt) and ask which to use.
- None → no summarizer scanner exists. See
**No summarizer scanner? Run a temporary one** below.
3. **Scan the session** with the chosen scanner. Warn this is async and takes several minutes (rasterize + LLM):
posthog:vision-scanners-scan-session
{
"id": "<scanner_id>",
"session_id": "<session_id>"
}4. **Retrieve the result** by polling `vision-observations-list` (step 1) until the new observation reaches `succeeded`.
No summarizer scanner? Run a temporary
:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.
Repo: posthog/posthog
Other skills on posthog.
- /analyzing-expensive-users
Analyze the most expensive users in AI observability and explain why they cost so much. Use when the user asks about top spenders, expensive users, per-user LLM cost, user-level cost drivers, or patterns behind high AI observability spend.
Open skill - /creating-online-evaluations
Author continuously-running online evaluations in PostHog AI observability, grounded in real failure modes you've identified. Use when the user wants evaluations that automatically score new generations or whole traces going forward — "create an eval to catch X", "continuously
Open skill - /exploring-ai-failures
Find where an AI/LLM application is failing in production and surface the failure patterns, working from real traces. Use when someone wants to understand what's going wrong with an AI feature, find and categorize failure modes, triage errors, or investigate quality issues
Open skill - /exploring-llm-clusters
Investigate AI observability clusters — understand usage patterns in AI/LLM traffic, compare cluster behavior, compute cost/latency metrics, and drill into individual traces within clusters.
Open skill - /exploring-llm-costs
Investigate LLM spend in PostHog — total cost over time, cost by model, provider, user, trace, or custom dimension, token and cache-hit economics, and cost regressions. Use when the user asks "how much are we spending on LLMs?", "which model / user / feature is most expensive?",
Open skill - /exploring-llm-evaluations
Investigate AI observability evaluations — `hog` (deterministic code-based), `llm_judge` (LLM-prompt-based), and `sentiment` (user-message sentiment). Find existing evaluations, inspect their configuration, run them against specific generations, query individual results, and
Open skill

