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_submittedevents - A deployed TaskJunky web app, usually
https://web.taskjunky.app - A shared webhook secret configured as
POSTHOG_WEBHOOK_SECRETin TaskJunky - A TaskJunky user id configured as
MCP_USER_IDin 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.appweb.taskjunky.appYou 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/webhookIf you are self-hosting TaskJunky, replace the domain with your own web app base URL.
Configure PostHog
In PostHog:
- Open Data pipeline or Actions, depending on your PostHog UI.
- Create or select the event flow for
feedback_submitted. - Add a Webhook destination.
- Set the destination URL to
https://web.taskjunky.app/api/posthog/webhook. - Add this header:
Authorization: Bearer <POSTHOG_WEBHOOK_SECRET>- Configure the payload as JSON and include the event name, properties, distinct id, and timestamp.
- 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:
eventis exactlyfeedback_submittedproperties.sentimentis one ofloved,meh, orfrustratedproperties.triggeris a stringproperties.app_versionis a string
These additional properties are also supported:
properties.noteproperties.surfaceproperties.device_modelproperties.is_pro_userproperties.user_emailproperties.was_negative_beforeproperties.is_resolutionproperties.bundle_idif you want to include a native app's bundle identifier in the feedback loop payload for debugging or downstream routingproperties.app_idif you want to include a stable app identifier for routingproperties.project_idif you want to route by TaskJunky project idproperties.project_nameif you want to route by TaskJunky project namedistinct_idtimestamp
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
frustratedfeedback becomes anurgenttaskmehfeedback becomes ahightasklovedfeedback becomes alowtask- Resolution events with
is_resolution: trueare created withlowpriority andin_reviewstatus - Tasks are created with
source: "api"and assigned to the configuredMCP_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: theAuthorizationheader does not matchBearer <POSTHOG_WEBHOOK_SECRET>422 Invalid payload structure: one of the required fields is missing orsentimentis not one of the supported values500 Server misconfigured:POSTHOG_WEBHOOK_SECRETorMCP_USER_IDis 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"