PostHog
Use this skill for PostHog product analytics work: event capture, person property reads and updates, feature flag inspection, feature flag test evaluation, and bounded insight/HogQL queries.
Scope
- capture a single product analytics event through the public capture endpoint
- update person properties with a guarded
$identifycapture event - list and retrieve persons through the private persons API
- list and retrieve feature flag metadata
- test how a feature flag evaluates for a distinct id without changing the flag
- run private query API requests for HogQL, trends, funnels, retention, and other PostHog query payloads
- classify common PostHog auth, permission, validation, and rate-limit errors
- measure skill run cost through normal HybridClaw
UsageTotals
Out Of Scope
- creating, editing, rolling out, or deleting feature flags
- deleting persons or bulk deleting data
- bulk historical imports or migration-sized batch capture
- exporting large event/person tables on a schedule
- bypassing PostHog region, project, environment, or credential configuration
Credential Rules
PostHog has two credential rails:
POSTHOG_PROJECT_TOKENis the public project token used in capture payloads.POSTHOG_PERSONAL_API_KEYis a private bearer credential used for persons, feature flags, and query endpoints.
Never paste either token into chat or helper arguments. The helper emits
<secret:POSTHOG_PROJECT_TOKEN> inside capture JSON and
bearerSecretName: "POSTHOG_PERSONAL_API_KEY" for private APIs, so the gateway
injects credentials server-side.
Recommended setup order:
- Browser admin: open the active HybridClaw admin URL ending in
/admin/secretsand setPOSTHOG_PROJECT_TOKENandPOSTHOG_PERSONAL_API_KEY. - Browser
/chator TUI fallback:
/secret set POSTHOG_PROJECT_TOKEN <project-token>
/secret set POSTHOG_PERSONAL_API_KEY <personal-api-key>
/env set POSTHOG_HOST "https://us.posthog.com"
/env set POSTHOG_INGEST_HOST "https://us.i.posthog.com"
/env set POSTHOG_PROJECT_ID "12345"
/env set POSTHOG_ENVIRONMENT_ID "12345"
- Local console fallback:
hybridclaw secret set POSTHOG_PROJECT_TOKEN "<project-token>"
hybridclaw secret set POSTHOG_PERSONAL_API_KEY "<personal-api-key>"
hybridclaw env set POSTHOG_HOST "https://us.posthog.com"
hybridclaw env set POSTHOG_INGEST_HOST "https://us.i.posthog.com"
hybridclaw env set POSTHOG_PROJECT_ID "12345"
hybridclaw env set POSTHOG_ENVIRONMENT_ID "12345"
Use the right regional hosts. For PostHog US Cloud, private API calls use
https://us.posthog.com and capture calls use https://us.i.posthog.com. For
EU Cloud, use https://eu.posthog.com and https://eu.i.posthog.com. For
self-hosted deployments, use the self-hosted base URL for both when that is how
the instance is exposed.
Default Workflow
- Use
planfor natural-language requests when you need to classify read vs write risk before executing. - Run the bundled helper for live PostHog calls so request construction,
gateway submission, credentials, and error interpretation stay in one place:
node skills/posthog/posthog.cjs --format json run ... - Use
http-requestonly when you need to inspect the generated request or when a runtime exposes the built-inhttp_requesttool but cannot run the helper against the gateway directly:node skills/posthog/posthog.cjs --format json http-request ... - Pass only the emitted
httpRequestobject to the built-inhttp_requesttool in that fallback path. Do not handcraft PostHog API calls from memory. - For amber operations, run
approval-planfirst, get explicit operator confirmation, then rerun the exact helper command with--operator-grant. - Keep capture payloads small and business-relevant. Do not send passwords, access tokens, full message bodies, contracts, or raw support transcripts as event/person properties.
- If a live PostHog call returns 401 or 403, stop after that first failure and ask the operator to verify the matching stored credential and scopes.
- If a private response is paginated and includes
next, call the next URL only when the user needs another page.
Command Contract
Inspect the helper surface:
node skills/posthog/posthog.cjs --help
Plan a request without contacting PostHog:
node skills/posthog/posthog.cjs --format json plan "Show active flags for checkout"
node skills/posthog/posthog.cjs --format json plan "Capture a trial_started event for user_123"
Build an approval plan for a capture write:
node skills/posthog/posthog.cjs --format json approval-plan capture-event \
--event trial_started \
--distinct-id user_123 \
--properties-json '{"plan":"pro"}'
Capture a single event after explicit approval:
node skills/posthog/posthog.cjs --format json run capture-event \
--event trial_started \
--distinct-id user_123 \
--properties-json '{"plan":"pro"}' \
--operator-grant
node skills/posthog/posthog.cjs --format json http-request capture-event \
--event trial_started \
--distinct-id user_123 \
--properties-json '{"plan":"pro"}' \
--operator-grant
Update person properties after explicit approval:
node skills/posthog/posthog.cjs --format json http-request identify-person \
--distinct-id user_123 \
--set-json '{"company":"Acme GmbH","plan":"pro"}' \
--operator-grant
Read persons:
node skills/posthog/posthog.cjs --format json run list-persons \
--environment-id 12345 \
--search acme \
--limit 50
node skills/posthog/posthog.cjs --format json http-request get-person \
--environment-id 12345 \
--person-id 018f6c8f-...
Read feature flags and test evaluation:
node skills/posthog/posthog.cjs --format json http-request list-feature-flags
node skills/posthog/posthog.cjs --format json http-request get-feature-flag \
--flag-id 42
node skills/posthog/posthog.cjs --format json http-request test-feature-flag \
--flag-id 42 \
--distinct-id user_123
Run an analytics query:
node skills/posthog/posthog.cjs --format json http-request query \
--hogql "select event, count() from events where timestamp > now() - interval 7 day group by event order by count() desc limit 10"
Use --query-json for PostHog query payloads beyond HogQL:
node skills/posthog/posthog.cjs --format json http-request query \
--query-json '{"kind":"TrendsQuery","series":[{"kind":"EventsNode","event":"$pageview"}]}'
Interpret a saved http_request error:
node skills/posthog/posthog.cjs --format json explain-error --payload-file /tmp/posthog-error.json