PostHog

Lightweight, dependency-free, in-memory PostHog API fake for testing code that uses the real posthog-node / posthog-js SDKs (and the language-agnostic PostHog REST API).

Default port: 4807

Quick start

import { PosthogServer } from "./services/posthog/src/server.js";

const server = new PosthogServer(4807);
await server.start();
// ... run your app/tests ...
await server.stop();

Point the real posthog-node client at it via the host option:

import { PostHog } from "posthog-node";

const client = new PostHog("phc_parlel_test_key", {
  host: "http://127.0.0.1:4807",
});

client.capture({ distinctId: "user-123", event: "user signed up", properties: { plan: "pro" } });
await client.flush();

Every captured event is held in memory and can be inspected via the /__parlel/* endpoints.

Implemented operations

Event ingestion uses the project api_key in the request body (no bearer required). The /api/* REST surface requires Authorization: Bearer <personal-api-key>.

Event ingestion

Project REST API (/api/projects/:id)

Service & inspection operations (parlel extensions)

Access via MCP / preview URL

When run inside a parlel pool, the service is reachable at its preview URL (the host/port shown by the pool). Configure your SDK's host to that URL. Through the parlel MCP server, the service is exposed as a tool surface so an AI agent can drive captures and query events without leaving the editor — the same /capture/, /batch/, /decide/ and /api/projects/:id/* routes are available.

Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

FeatureStatus
capture / batch event ingestion✅ Supported
/decide feature flag evaluation✅ Supported
Insights CRUD✅ Supported
Events query✅ Supported
Captured-event inspection✅ Supported (parlel extension)
Real analytics computation / aggregation✓ By design — Not computed (insights return empty result)
Cohorts / Trends / Funnels math⟳ Roadmap
Session recording ingestion⟳ Roadmap
Bearer-token validity / scope enforcement✓ By design — Any non-empty credential is accepted — no real secrets needed

Manifest

See services/posthog/manifest.json:

<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

POSTHOG_API_KEY=phc_parlel
POSTHOG_PERSONAL_API_KEY=phx_parlel
POSTHOG_HOST=http://parlel-bridge:4807
POSTHOG_BASE_URL=http://parlel-bridge:4807
<!-- parlel:testenv:end -->