Pulumi Any Terraform

Insight

Create and manage analytics insights and queries

The Insight resource allows you to create and manage analytics insights for tracking events, funnels, retention, and other metrics in PostHog.

Example Usage

import * as posthog from "pulumi-posthog";

const pageviews = new posthog.Insight("pageviews", {
    name: "Pageview Trends",
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "$pageview",
            name: "Pageviews",
        }],
        dateRange: {
            date_from: "-30d",
        },
    }),
});

Signup Tracking

const signups = new posthog.Insight("signups", {
    name: "User Signups",
    description: "Track new user registrations",
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "user_signed_up",
            name: "User Signed Up",
        }],
        dateRange: {
            date_from: "-30d",
        },
    }),
});

Retention Analysis

const retention = new posthog.Insight("retention", {
    name: "User Retention",
    description: "Track how many users return after signup",
    queryJson: JSON.stringify({
        kind: "RetentionQuery",
        retentionFilter: {
            targetEntity: {
                id: "user_signed_up",
                type: "events",
            },
            returningEntity: {
                id: "$pageview",
                type: "events",
            },
        },
        dateRange: {
            date_from: "-90d",
        },
    }),
});

Insight on Dashboard

const dashboardInsight = new posthog.Insight("dashboard-metric", {
    name: "Key Metric",
    dashboardIds: [12345], // Add to specific dashboard
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "purchase_completed",
        }],
        dateRange: { date_from: "-7d" },
    }),
});

Insight with Tags

const taggedInsight = new posthog.Insight("tagged-insight", {
    name: "Mobile App Sessions",
    tags: ["mobile", "engagement", "daily"],
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "app_session_start",
        }],
        dateRange: { date_from: "-30d" },
    }),
});

Funnel Analysis

const funnel = new posthog.Insight("conversion-funnel", {
    name: "Signup to Purchase Funnel",
    description: "Track user journey from signup to first purchase",
    queryJson: JSON.stringify({
        kind: "FunnelsQuery",
        series: [
            {
                kind: "EventsNode",
                event: "user_signed_up",
                name: "Signed Up",
            },
            {
                kind: "EventsNode",
                event: "added_to_cart",
                name: "Added to Cart",
            },
            {
                kind: "EventsNode",
                event: "purchase_completed",
                name: "Purchased",
            },
        ],
        dateRange: {
            date_from: "-30d",
        },
    }),
});

Resource Properties

Required Arguments

  • queryJson (string): Raw JSON serialized query payload accepted by PostHog (e.g., InsightVizNode with a TrendsQuery)

Optional Arguments

  • name (string): Insight name
  • description (string): Insight description
  • dashboardIds (number[]): List of dashboard IDs to add the insight to
  • createInFolder (string): Folder where the insight is created
  • tags (string[]): List of tags to apply to the insight
  • deleted (boolean): Whether the insight is deleted (soft delete)
  • derivedName (string): Insight derived name (auto-generated by PostHog when name is not set)

Attributes

  • insightId: Numeric insight ID
  • name: Insight name
  • derivedName: Auto-generated insight name

Query Types

PostHog supports several query types:

TrendsQuery

Track event volumes over time:

queryJson: JSON.stringify({
    kind: "TrendsQuery",
    series: [{
        kind: "EventsNode",
        event: "event_name",
    }],
    dateRange: { date_from: "-30d" },
})

FunnelsQuery

Analyze conversion funnels:

queryJson: JSON.stringify({
    kind: "FunnelsQuery",
    series: [
        { kind: "EventsNode", event: "step_1" },
        { kind: "EventsNode", event: "step_2" },
        { kind: "EventsNode", event: "step_3" },
    ],
    dateRange: { date_from: "-30d" },
})

RetentionQuery

Measure user retention:

queryJson: JSON.stringify({
    kind: "RetentionQuery",
    retentionFilter: {
        targetEntity: { id: "signup", type: "events" },
        returningEntity: { id: "$pageview", type: "events" },
    },
    dateRange: { date_from: "-90d" },
})

Best Practices

1. Use Descriptive Names

// ✅ Good
const insight = new posthog.Insight("user-engagement", {
    name: "Daily Active Users - Last 30 Days",
    description: "Number of unique users who performed any action",
});

// ❌ Avoid
const insight = new posthog.Insight("insight1", {
    name: "Insight 1",
});

2. Add to Relevant Dashboards

const insight = new posthog.Insight("key-metric", {
    name: "Revenue Trend",
    dashboardIds: [123, 456], // Add to multiple dashboards
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{ kind: "EventsNode", event: "purchase" }],
        dateRange: { date_from: "-30d" },
    }),
});

3. Use Tags for Organization

const insight = new posthog.Insight("mobile-metric", {
    name: "Mobile App Launches",
    tags: ["mobile", "engagement", "ios", "android"],
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{ kind: "EventsNode", event: "app_launched" }],
        dateRange: { date_from: "-7d" },
    }),
});

Common Use Cases

User Engagement Tracking

const engagement = new posthog.Insight("engagement", {
    name: "Daily Active Users",
    description: "Unique users per day",
    tags: ["engagement", "daily"],
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "$pageview",
            math: "dau", // Daily active users
        }],
        dateRange: { date_from: "-30d" },
    }),
});

Feature Adoption

const adoption = new posthog.Insight("feature-adoption", {
    name: "New Feature Usage",
    description: "Track adoption of newly released feature",
    tags: ["product", "feature"],
    queryJson: JSON.stringify({
        kind: "TrendsQuery",
        series: [{
            kind: "EventsNode",
            event: "new_feature_used",
        }],
        dateRange: { date_from: "-90d" },
    }),
});

Conversion Tracking

const conversion = new posthog.Insight("conversion", {
    name: "Signup to Trial Conversion",
    description: "Users who start trial after signing up",
    queryJson: JSON.stringify({
        kind: "FunnelsQuery",
        series: [
            { kind: "EventsNode", event: "user_signed_up" },
            { kind: "EventsNode", event: "trial_started" },
        ],
        dateRange: { date_from: "-30d" },
    }),
});

Troubleshooting

Invalid Query JSON

Issue: Error creating insight with invalid query

Solution:

  • Ensure queryJson is a valid JSON string
  • Use JSON.stringify() to convert objects to JSON strings
  • Validate query structure matches PostHog's query schema
// ✅ Correct - use JSON.stringify()
queryJson: JSON.stringify({
    kind: "TrendsQuery",
    series: [{ kind: "EventsNode", event: "$pageview" }],
})

// ❌ Incorrect - queryJson must be a string, not an object
queryJson: { kind: "TrendsQuery" } // This will fail

Insight Not Showing Data

Issue: Insight created but shows no data

Solution:

  • Verify the event name exists in PostHog
  • Check the date range includes data
  • Confirm events are being captured

Dashboard Assignment Fails

Issue: Cannot add insight to dashboard

Solution:

  • Use numeric dashboard IDs (from PostHog)
  • Ensure dashboard exists before creating insight
  • Verify you have access to the dashboard

Additional Resources

On this page