TaskJunkyDocs

PostHog Feedback Loop

Route PostHog feedback events into TaskJunky as feedback tasks.

What this does

This guide is specifically for the PostHog feedback loop.

TaskJunky exposes a PostHog webhook endpoint that turns feedback_submitted events into tasks in a User Feedback list.

Each accepted event creates a task for the configured TaskJunky user and includes the feedback note, sentiment, app version, device info, and user email when present.

Before you start

You need:

  • A PostHog project where your app sends feedback_submitted events
  • A deployed TaskJunky web app, usually https://web.taskjunky.app
  • A shared webhook secret configured as POSTHOG_WEBHOOK_SECRET in TaskJunky
  • A TaskJunky user id configured as MCP_USER_ID in TaskJunky so the created tasks have an owner
  • An app identifier only if you also want to configure per-app routing in TaskJunky developer settings

App identifier

For the feedback loop, TaskJunky's Settings > Developer > Webhook Routing settings now use ordered routing rules instead of a single app-keyed map.

This is optional for the current dedicated PostHog feedback webhook. The webhook handler can match rules by project, app identifier, or both.

If you do want app-specific routing, use a stable identifier:

  • Native iOS or mobile apps: usually the bundle identifier
  • Web apps: a consistent identifier you define

Examples:

com.taskjunky.app
web.taskjunky.app

You can also match by project_id or project_name in the webhook payload, which is often cleaner for contact forms or multi-project intake.

Endpoint

Send the webhook to:

https://web.taskjunky.app/api/posthog/webhook

If you are self-hosting TaskJunky, replace the domain with your own web app base URL.

Configure PostHog

In PostHog:

  1. Open Data pipeline or Actions, depending on your PostHog UI.
  2. Create or select the event flow for feedback_submitted.
  3. Add a Webhook destination.
  4. Set the destination URL to https://web.taskjunky.app/api/posthog/webhook.
  5. Add this header:
Authorization: Bearer <POSTHOG_WEBHOOK_SECRET>
  1. Configure the payload as JSON and include the event name, properties, distinct id, and timestamp.
  2. Send a test event from PostHog and confirm TaskJunky creates a task in User Feedback.

If you want custom routing, open Settings > Developer > Webhook Routing in TaskJunky and add one or more ordered routing rules. Rules can match by project, app identifier, or both, and blank match fields act as catch-all rules.

Required payload

The webhook handler only processes events where:

  • event is exactly feedback_submitted
  • properties.sentiment is one of loved, meh, or frustrated
  • properties.trigger is a string
  • properties.app_version is a string

These additional properties are also supported:

  • properties.note
  • properties.surface
  • properties.device_model
  • properties.is_pro_user
  • properties.user_email
  • properties.was_negative_before
  • properties.is_resolution
  • properties.bundle_id if you want to include a native app's bundle identifier in the feedback loop payload for debugging or downstream routing
  • properties.app_id if you want to include a stable app identifier for routing
  • properties.project_id if you want to route by TaskJunky project id
  • properties.project_name if you want to route by TaskJunky project name
  • distinct_id
  • timestamp

Example payload:

{
  "event": "feedback_submitted",
  "distinct_id": "user_123",
  "timestamp": "2026-03-29T18:45:00.000Z",
  "properties": {
    "sentiment": "frustrated",
    "note": "The task detail panel feels slow when I open subtasks.",
    "trigger": "manual",
    "surface": "web_app",
    "app_version": "1.0.6",
    "device_model": "MacBookPro18,3",
    "is_pro_user": true,
    "bundle_id": "com.taskjunky.app",
    "user_email": "user@example.com",
    "was_negative_before": true,
    "is_resolution": false
  }
}

How TaskJunky maps the event

  • frustrated feedback becomes an urgent task
  • meh feedback becomes a high task
  • loved feedback becomes a low task
  • Resolution events with is_resolution: true are created with low priority and in_review status
  • Tasks are created with source: "api" and assigned to the configured MCP_USER_ID
  • App identifiers entered in Settings > Developer > Webhook Routing are optional and only used for per-app routing conventions

If the User Feedback list does not exist yet, TaskJunky creates it automatically.

Troubleshooting

  • 401 Unauthorized: the Authorization header does not match Bearer <POSTHOG_WEBHOOK_SECRET>
  • 422 Invalid payload structure: one of the required fields is missing or sentiment is not one of the supported values
  • 500 Server misconfigured: POSTHOG_WEBHOOK_SECRET or MCP_USER_ID is missing in the TaskJunky deployment
  • Webhook says success but no task appears: make sure the event name is exactly feedback_submitted

Client-side example

This is the event shape TaskJunky expects your app to send to PostHog:

posthog.capture("feedback_submitted", {
  sentiment: "frustrated",
  note: "The task detail panel feels slow when I open subtasks.",
  trigger: "manual",
  surface: "web_app",
  app_version: "1.0.6",
  device_model: "MacBookPro18,3",
  is_pro_user: true,
  user_email: "user@example.com",
});

For native apps, you can also include:

bundle_id: "com.taskjunky.app"

On this page