Skip to main content
The PostHog integration is a read-only runner SDK family for bounded analytics and operational composition. It can discover events, properties, tables, and fields, run parameterized HogQL, resolve ephemeral behavioral populations, enrich explicit external user IDs, and read a compact activity timeline. It does not manage PostHog dashboards, flags, experiments, or surveys. Use PostHog directly for those workflows. Polycore is useful when PostHog behavior needs to be combined with authoritative state from Postgres, Firestore, or an internal API without syncing those systems into PostHog.

Architecture

The PostHog API key remains on the runner host. Query results return through the normal governed invocation and audit path.

Configure the family

Commit only the PostHog host and env-var names:
polycore.json
projectIdEnv, apiKeyEnv, and limits.maxLookbackDays default to the values shown. EU Cloud uses https://eu.posthog.com. Self-hosted installations may use their own HTTPS origin; HTTP is accepted only for localhost evaluation. The host cannot contain credentials, a path, query parameters, or a fragment. Inject runtime values through the runner deployment:
Use a dedicated PostHog key with only the scopes the enabled reads need:
  • query:read for HogQL and actor-oriented capabilities.
  • event_definition:read for posthog.listEvents.
  • property_definition:read for posthog.listProperties.
The family exposes no provider mutations, so it needs no write scopes.

Available capabilities

read
Lists up to 500 event definitions with names, descriptions, tags, verification, visibility, and last-seen metadata. Supports exact-name filtering and bounded offset pagination.
read
Lists up to 500 event, person, group, or session property definitions. Supports search, event-name filters, and bounded offset pagination.
read
Lists PostHog core/system tables, imported warehouse tables, saved and materialized views, managed views, batch exports, and endpoints. Supports search, type filters, and bounded pagination.
read
Describes one exact table from posthog.listTables, including bounded fields, HogQL expressions, serialized types, validity, nested-field hints, row count, and catalog certification where available.
read
Runs one parameterized HogQL SELECT or WITH query. Results are capped at 1,000 rows, 200 columns, and 64 KiB. This is for bounded ad-hoc analytics, not event/person exports.
read
Resolves an ephemeral population from event-count criteria and event/person property filters. Returns recent distinct-ID aliases, criterion counts, and last activity for at most 500 people. It does not persist a PostHog cohort.
read
Enriches up to 100 explicit external distinct IDs with event counts, active days, and first/last matching activity. PostHog’s person_distinct_ids mapping includes history merged from anonymous identifiers.
read
Returns up to 200 recent events for one external distinct ID. Event names and returned properties are explicit; elements_chain is excluded by default.

Parameterized HogQL

Never interpolate caller-controlled text into HogQL. Use PostHog’s constant placeholders:
The runner wraps the query in an outer LIMIT, so a larger limit inside the HogQL cannot bypass the configured result ceiling. PostHog also limits query execution and concurrency at project level. Include short time windows and aggregate in PostHog rather than returning raw events.

Operational composition

Enrich records from another system

  1. Read a bounded account or user list from Postgres/Firestore.
  2. Pass its external IDs to posthog.enrich.
  3. Join the returned behavioral facts into a Polycore page or agent answer.
For example, a renewal queue can add last activity, active days, and key-feature usage without sending billing or account tables to PostHog.

Resolve behavior, then read authoritative state

  1. Use posthog.segment to identify people who performed or missed selected behavior.
  2. Resolve the returned distinct IDs in the system of record.
  3. Present the combined evidence or propose an operation through a separate, approval-gated customer action.
Keep lists bounded. For an exact join over thousands of people, create a named composite read action that performs both reads inside the runner and returns only aggregates or a small opportunity list.

Composite read actions

The runner SDK exports PostHogClient for reviewed actions that need to combine PostHog with another local client without routing an intermediate actor set through the control plane. It exposes the same bounded parameterized HogQL and taxonomy reads as the built-in family:
The action should still keep the API key read-only and return a small declared output. Use the built-in capabilities unless the join itself must stay entirely inside the runner or is a durable domain operation.

Identity behavior

posthog.enrich and posthog.activity resolve an external distinct ID through PostHog’s person_distinct_ids table, then query by PostHog person ID. This includes events captured under anonymous identifiers that PostHog later merged into the same person. posthog.segment returns all recent distinct-ID aliases observed for each matched person. The caller should select the identifier used by its system of record rather than assuming the latest browser identifier is canonical.

Enforced limits

  • Raw HogQL: 20,000 input characters, 1,000 returned rows, 200 columns.
  • Event/property definitions and table inventory: 500 per invocation.
  • Table description: 1,000 fields with bounded pagination.
  • Segment: 10 criteria, 10 property filters per criterion, 500 people.
  • Enrichment: 100 distinct IDs and 20 metrics.
  • Activity: 200 events, 50 event names, 20 selected properties.
  • Every capability result: 64 KiB.
  • Upstream HTTP response: 4 MB.
  • Default request timeout: 45 seconds.
  • Actor lookback: at most maxLookbackDays from committed config.
Transient throttles and selected provider failures are retried with a small, bounded backoff. Requests never follow a provider-supplied URL, and callers cannot change the configured host or project.

Production validation

Event/property discovery and table/field introspection return the intended project taxonomy and database catalog.
A parameter containing quotes and SQL operators round-trips as a value instead of changing query structure.
A broad query is truncated below the row and byte limits.
Segment aliases can be resolved to the identifiers used by the system of record.
Enrichment includes merged anonymous history for a known identified user.
Missing scopes, throttling, malformed provider responses, and timeouts fail clearly without logging the API key.