Hogsend is brand new.Chat to Doug
Hogsend
IntegrationsPostHog

PostHog

The full PostHog integration — events in, person reads, engagement out, person writes — set up by one scaffold prompt and one `hogsend connect posthog` command.

PostHog is where most Hogsend apps start: it already knows what your users do, and Hogsend turns that into lifecycle email. The integration runs in both directions — PostHog events trigger journeys, journeys read person properties, and everything Hogsend does (sends, opens, clicks, journey completions) fans back out onto the same PostHog persons.

Setting all of that up used to be a dashboard walkthrough. Now it's two moments:

# 1. At scaffold time — answers one prompt, writes the env
npx create-hogsend@latest my-app

# 2. Once deployed — one command, one browser consent click
hogsend connect posthog --url https://api.your-app.com

The scaffold asks "Are you using PostHog?" — you can hand it your project API key and region (it writes POSTHOG_API_KEY + POSTHOG_HOST and switches on the outbound destination), or skip the key entirely and let hogsend connect posthog fetch it after deploy. Either way, hogsend connect posthog finishes the loop: a PKCE OAuth flow stores an encrypted credential on your instance (wiring person reads), reads the project's public key for the outbound capture path, mints and persists the webhook signing secret if you haven't set one, and provisions the PostHog → Hogsend webhook destination for you — idempotently, so re-running it adopts an existing destination rather than creating a duplicate.

What the integration does

Five things, each independently useful:

DirectionWhat happensSet up by
Events inIdentified PostHog events POST to /v1/webhooks/posthog and trigger journeyshogsend connect posthog, or by hand
Person readsJourneys resolve per-user timezones (ctx.when) and evaluate person-property conditionsThe connect flow's OAuth credential, or a personal API key
Engagement outEmail lifecycle events (sent, opened, clicked, bounced…) land in your PostHog project, durablyENABLE_POSTHOG_DESTINATION=true — the scaffold sets it; see destinations
Person writesContact properties propagate onto PostHog persons ($set via the project key) — syncPersons is on by default for the seeded destinationSame seeded destination
One identitySite sessions, email clicks, and analytics persons join on one canonical contact key — round-trip safe, so events forwarded back never create duplicatesThe identity loop

How it's wired

PostHog is deliberately not one of the signed engine presets (Clerk, Supabase, Stripe, Segment). The inbound receiver ships in your scaffold — src/webhook-sources/posthog.ts, a defineWebhookSource() you own and can reshape — and it authenticates with a plain shared secret (POSTHOG_WEBHOOK_SECRET), because PostHog's webhook destinations send a header you configure rather than a signature.

The rest is engine-owned: the AnalyticsProvider contract behind person reads and writes (PostHog is the reference implementation, not the architecture — see Analytics access & identity), the outbound posthog destination preset on the durable delivery spine, and the OAuth credential store + provisioner behind the connect command.

None of this is required to boot. Hogsend runs entirely on its own data plane — POST /v1/events and the client SDK — and PostHog layers on whenever you're ready.

The pages

On this page