mcp-servers
Install, configure, authenticate, and troubleshoot MCP (Model Context Protocol) servers for this agent. Use when the user asks to…
Implements a PostHog API (headless) survey inside the user's own codebase so it renders with their UI components and captures the exact events PostHog expects, then verifies the first response arrived. Use when asked to implement a survey, build a headless survey, build a custom
$ npx -y skills add posthog/posthog --skill implementing-api-surveys --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/implementing-api-surveysContext preview
The summary Claude sees to decide when to auto-load this skill.
Implements a PostHog API (headless) survey inside the user's own codebase so it renders with their UI components and captures the exact events PostHog expects, then verifies the first response arrived. Use when asked to implement a survey, build a headless survey, build a custom
name: implementing-api-surveys description: > Implements a PostHog API (headless) survey inside the user's own codebase so it renders with their UI components and captures the exact events PostHog expects, then verifies the first response arrived. Use when asked to implement a survey, build a headless survey, build a custom survey UI, render a survey in my app, or wire up a survey of type `api` in a browser, server, or custom mobile UI. Covers the posthog-js event contract, server-side SDK capture, and post-implementation verification through MCP. To design or create the survey definition, use creating-surveys instead. For a survey that is implemented but not showing or not recording, use debugging-surveys.
An `api` survey is only a definition in PostHog. PostHog does not render it. The application renders the questions and captures the survey events. If the events or their properties are wrong, responses are missing, double-counted, or unattributed.
Fetch it with `posthog:survey-get` by `id`. Note each question's `id`, `type`, `question`, choices, scale and `optional`, plus `current_iteration`. Never invent question ids.
If the survey does not exist yet, create it first with the `creating-surveys` skill (type `api`). Design guidance (short, rating or choice first, open text second) lives there too. Do not restate it here.
Before writing UI, find:
Pick the path:
Require posthog-js 1.249.2 or newer. Older versions do not set the person properties and seen state on capture. Tell the user to upgrade rather than adding them by hand.
The lookup only works once both flags and the surveys bundle have loaded, because targeting is evaluated with flags and `getActiveMatchingSurveys` does nothing before surveys load. Register one retry for each at startup, and guard against rendering twice, since `onFeatureFlags` also runs on every flag reload (after `identify`, and after each response).
let triggered = false
let rendered = false
function tryShowSurvey() {
if (!triggered || rendered) return
posthog.getActiveMatchingSurveys((surveys) => {
const survey = surveys.find((s) => s.id === SURVEY_ID)
if (!survey || rendered) return
rendered = true
renderSurvey(survey)
})
}
// Register once at startup, not per trigger.
posthog.onFeatureFlags(tryShowSurvey)
posthog.onSurveysLoaded(tryShowSurvey)
function showSurveyIfEligible() {
triggered = true
tryShowSurvey()
}
// Call when the survey closes, after the final send or a dismiss.
function onSurveyClosed() {
triggered = false
rendered = false
}Call `showSurveyIfEligible()` from the app's trigger, such as after a checkout completes, or right after setup if the survey belongs on page load. Call `onSurveyClosed()` when the survey closes, so a survey that can repeat shows again on the next trigger. A survey that cannot repeat stays hidden, because posthog-js marks it as seen. In a single-page app, register the two listeners where the app initializes PostHog, and call the functions they return to unsubscribe if that code can unmount. `SURVEY_ID` is the id from step 1. `renderSurvey` mounts the component you build from the app's own UI, and that component calls the handlers below. `getActiveMatchingSurveys` applies the survey's targeting for this person, so render only what it returns.
Capture three events. `answers` maps each question id to its answer, and holds every answer given so far in this submission. Exact property names and value shapes are in [event-contract.md](references/event-contract.md).
function onShown(survey) {
posthog.capture('survey shown', {
$survey_id: survey.id,
$survey_iteration: survey.current_iteration,
})
// posthog-js reads this key for the survey wait period; only its own renderer writes it.
try {
localStorage.setItem('lastSeenSurveyDate', new Date().toISOString())
} catch {}
}
function onSubmit(survey, answers, submissionId, completed) {
posthog.capture('survey sent', {
$survey_id: survey.id,
$survey_iteration: survey.current_iteration,
$survey_submission_id: submissionId,
$survey_completed: completed,
$survey_questions: survey.questions.map(({ id, question }) => ({ id, question })),
...Object.fromEntries(
Object.entries(answers).map(([questionId, value]) => [`$survey_response_${questionId}`, value])
),
})
}
function onDismiss(survey) {
posthog.capture('survey dismissed', {
$survey_id: survey.id,
$survey_iteration: survey.current_iteration,
})
}Rules that cause silent data problems:
: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.
Install, configure, authenticate, and troubleshoot MCP (Model Context Protocol) servers for this agent. Use when the user asks to…
Designs and runs task-specific JavaScript harnesses with the `workflow` tool. Use for broad, long-running, highly structured, or…
How and when to delegate work to subagents via the `subagent` tool (Explore, Plan, General). Use when a task involves codebase…
Explains what a member or a role can do in a PostHog project, using the access control MCP tools. Use when the user asks what…
Analyze the most expensive users in AI observability and explain why they cost so much. Use when the user asks about top…
Inspect and compare offline AI evaluation experiments, diagnose case-level regressions, and follow scorer history across…