# Understanding the Analytics Key Infrastructure in OpenWork

> Discover OpenWorks analytics key infrastructure. Learn how the analytics-key module dynamically resolves PostHog API keys using environment variables with smart fallbacks.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: architecture
- Published: 2026-08-06

---

**The analytics key infrastructure in OpenWork is built around the `analytics-key` module, which dynamically resolves PostHog API keys through environment variable detection with intelligent fallbacks for production and development environments.**

OpenWork implements a privacy-first telemetry system using PostHog to track application usage without exposing sensitive user data. The **analytics key infrastructure**, located in the `different-ai/openwork` repository, determines which analytics project receives events through a resolution mechanism defined in [`apps/app/src/app/lib/analytics-key.ts`](https://github.com/different-ai/openwork/blob/main/apps/app/src/app/lib/analytics-key.ts). This system enables self-hosted deployments and development builds to operate without sending data to third-party analytics platforms.

## Core Architecture of the Analytics Key System

The infrastructure centers on a single resolver function that determines the active PostHog key at runtime based on build configuration and environment variables.

### Key Resolution Logic

The `resolvePosthogKey` function in [`analytics-key.ts`](https://github.com/different-ai/openwork/blob/main/analytics-key.ts) implements a priority-based selection system:

1. **Custom Environment Variable** – If `VITE_OPENWORK_POSTHOG_KEY` is set as a string, it is trimmed and used as-is, allowing custom project keys or explicit disabling via empty strings.
2. **Development Fallback** – In development builds (`import.meta.env.DEV === true`), the function returns an empty string, effectively disabling analytics.
3. **Production Default** – Production builds use the hard-coded default key `phc_4YnPTlDVYPjgwKvLuNxhbHjV5kadgvd7XLzVHWnCXAI`.

```ts
// apps/app/src/app/lib/analytics-key.ts
export const DEFAULT_POSTHOG_KEY = "phc_4YnPTlDVYPjgwKvLuNxhbHjV5kadgvd7XLzVHWnCXAI";

export function resolvePosthogKey(raw: unknown, isDev: boolean): string {
  if (typeof raw === "string") return raw.trim();
  return isDev ? "" : DEFAULT_POSTHOG_KEY;
}

```

### Environment Variable Handling

The system relies on Vite's environment variable injection through `import.meta.env`. The [`analytics.ts`](https://github.com/different-ai/openwork/blob/main/analytics.ts) module initializes the constant `POSTHOG_KEY` by invoking the resolver with the raw environment value and development flag:

```ts
// apps/app/src/app/lib/analytics.ts
const POSTHOG_KEY = resolvePosthogKey(
  import.meta.env.VITE_OPENWORK_POSTHOG_KEY,
  import.meta.env.DEV
);

```

This design ensures that builds are deterministic while allowing runtime configuration through the `VITE_OPENWORK_POSTHOG_KEY` variable.

## Analytics Initialization and Event Flow

Once the key is resolved, the analytics client manages event queuing, batching, and transmission to PostHog's ingestion API.

### Event Capture and Batching

The `captureAnalyticsEvent` function queues events locally and mirrors them to an in-app inspector for debugging. Events are flushed in batches of **50** (`MAX_BATCH = 50`) to the endpoint `https://us.i.posthog.com/batch/`. If the resolved key is an empty string or the user has disabled analytics via the Settings UI (`analyticsEnabled` flag), the function early-returns before any network activity occurs.

```ts
// Conceptual usage from apps/app/src/app/lib/analytics.ts
import { captureAnalyticsEvent, isAnalyticsEnabled } from "@/app/lib/analytics";

if (isAnalyticsEnabled()) {
  captureAnalyticsEvent("feature_used", {
    feature: "dark_mode",
    duration_ms: 123,
  });
}

```

### Enterprise Gating

The analytics endpoint is protected by an "analytics" entitlement check. Servers return **402 Payment Required** status codes when the current plan does not support telemetry features, preventing unauthorized usage of the infrastructure.

## Configuration Examples

### Overriding the Analytics Key in Production

Deploy OpenWork with a custom PostHog project key by setting the environment variable before building:

```bash
export VITE_OPENWORK_POSTHOG_KEY=phc_custom_key_12345
pnpm build

```

### Disabling Analytics Completely

To ensure no telemetry data leaves the application, set the variable to an empty string:

```bash
export VITE_OPENWORK_POSTHOG_KEY=""
pnpm build

```

Development builds automatically disable analytics, but this method ensures production builds also operate without sending data.

### Programmatic Key Resolution

For custom modules requiring direct access to the resolved key:

```ts
import { resolvePosthogKey } from "@/app/lib/analytics-key";

const posthogKey = resolvePosthogKey(
  import.meta.env.VITE_OPENWORK_POSTHOG_KEY, 
  import.meta.env.DEV
);

if (posthogKey) {
  console.log("Analytics active with key:", posthogKey);
} else {
  console.log("Analytics disabled.");
}

```

## Summary

- The **analytics key infrastructure** centers on [`apps/app/src/app/lib/analytics-key.ts`](https://github.com/different-ai/openwork/blob/main/apps/app/src/app/lib/analytics-key.ts), which exports `resolvePosthogKey` and `DEFAULT_POSTHOG_KEY`.
- **Environment variable `VITE_OPENWORK_POSTHOG_KEY`** takes precedence over all defaults, with empty strings explicitly disabling analytics.
- **Development builds** automatically use empty keys to prevent local testing from polluting production datasets.
- **Event batching** occurs in chunks of 50 events to the PostHog `/batch` endpoint, with network calls skipped when keys are empty or analytics are disabled.
- **Unit tests** in [`apps/app/tests/analytics-key.test.ts`](https://github.com/different-ai/openwork/blob/main/apps/app/tests/analytics-key.test.ts) verify resolution logic across development, production, and custom override scenarios.

## Frequently Asked Questions

### How do I disable analytics in a self-hosted OpenWork instance?

Set the environment variable `VITE_OPENWORK_POSTHOG_KEY` to an empty string before building the application. According to the source code in [`analytics-key.ts`](https://github.com/different-ai/openwork/blob/main/analytics-key.ts), empty strings bypass the default production key and prevent the `captureAnalyticsEvent` function from initiating network requests.

### What happens if I don't set VITE_OPENWORK_POSTHOG_KEY?

In production builds, the system falls back to the hard-coded `DEFAULT_POSTHOG_KEY` (`phc_4YnPTlDVYPjgwKvLuNxhbHjV5kadgvd7XLzVHWnCXAI`). In development builds, the resolver returns an empty string, effectively disabling analytics to prevent local development data from reaching the analytics platform.

### Where is the analytics event data actually sent?

Events are batched and sent to `https://us.i.posthog.com/batch/` using the resolved PostHog key. However, the transmission only occurs if the key is non-empty, the user has enabled analytics in settings, and the account has the required "analytics" entitlement. The implementation in [`analytics.ts`](https://github.com/different-ai/openwork/blob/main/analytics.ts) ensures that no HTTP requests are made when these conditions are not met.

### Can I use my own PostHog project with OpenWork?

Yes. Set `VITE_OPENWORK_POSTHOG_KEY` to your custom project API key during the build process. The `resolvePosthogKey` function treats any string value as a valid override, trimming whitespace and using it instead of the default production key. This allows enterprise users to direct analytics to self-hosted PostHog instances or separate project workspaces.