Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/evaluate-flags-snapshot-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"posthog-server": minor
---

Add `evaluateFlags()` API for single-call flag evaluation. Returns a `PostHogFeatureFlagEvaluations` snapshot with `isEnabled` / `getFlag` / `getFlagPayload` / `getFlagPayloadAs<T>` accessors plus `onlyAccessed()` and `only(keys)` filters. `capture()` accepts the snapshot via a new `flags` parameter to attach `$feature/<key>` properties without a second `/flags` request; user-supplied `$feature/<key>` properties win over snapshot-derived ones. `$feature_flag_called` events now include `$feature_flag_id`, `$feature_flag_version`, `$feature_flag_reason`, and propagate `$feature_flag_error` (response-level errors plus `flag_missing` for unknown keys). `flagKeys` and `disableGeoip` are forwarded to the `/flags` request body and contribute to the per-identity cache key.

Deprecates `isFeatureEnabled`, `getFeatureFlag`, `getFeatureFlagPayload`, `getFeatureFlagResult`, and `capture(appendFeatureFlags = true)` in favour of `evaluateFlags(...)`. The legacy methods keep working unchanged; Kotlin callers see a `@Deprecated` compile-time warning (silenceable with `@Suppress("DEPRECATION")`) and the `appendFeatureFlags = true` capture path emits a one-line deprecation log. Removal targets the next major.
44 changes: 44 additions & 0 deletions posthog-server/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,50 @@ postHog.capture(

When `appendFeatureFlags` is `true`, the SDK will fetch feature flags for the user (or use locally evaluated flags if local evaluation is enabled) and include them in the event properties.

### Single-Call Flag Evaluation: `evaluateFlags()`

When you need to read several flags for the same user, call `evaluateFlags()` once and pass the resulting snapshot around. The snapshot answers `isEnabled` / `getFlag` / `getFlagPayload` from memory, dedups `$feature_flag_called` events per flag, and can be attached to a `capture()` call so the event is enriched without making another `/flags` request.

#### Kotlin

```kotlin
val flags = postHog.evaluateFlags("user123")

if (flags.isEnabled("new-checkout")) {
showNewCheckout()
}
val payload = flags.getFlagPayload("pricing-experiment")

// Attach only the flags actually consulted on this request to the capture event:
postHog.capture(
distinctId = "user123",
event = "purchase_completed",
properties = mapOf("amount" to 99.99),
flags = flags.onlyAccessed(),
)
```

#### Java

```java
PostHogFeatureFlagEvaluations flags = postHog.evaluateFlags("user123");

if (flags.isEnabled("new-checkout")) {
showNewCheckout();
}

postHog.capture(
"user123",
"purchase_completed",
PostHogCaptureOptions.builder()
.property("amount", 99.99)
.flags(flags.onlyAccessed())
.build()
);
```

`flagKeys` (an option on `evaluateFlags`) restricts what the server computes; the snapshot's `only(...)` helper, by contrast, filters in memory after the request.

## Error Tracking

PostHog provides error tracking to help you monitor and debug errors in your application. Use the `captureException` API to log exceptions to PostHog.
Expand Down
82 changes: 78 additions & 4 deletions posthog-server/api/posthog-server.api
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ public final class com/posthog/server/PostHog : com/posthog/PostHogStateless, co
public fun alias (Ljava/lang/String;Ljava/lang/String;)V
public fun capture (Ljava/lang/String;Ljava/lang/String;)V
public fun capture (Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogCaptureOptions;)V
public fun capture (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;Z)V
public fun capture (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;ZLcom/posthog/server/PostHogFeatureFlagEvaluations;)V
public fun captureException (Ljava/lang/Throwable;)V
public fun captureException (Ljava/lang/Throwable;Ljava/lang/String;)V
public fun captureException (Ljava/lang/Throwable;Ljava/lang/String;Ljava/util/Map;)V
public fun captureException (Ljava/lang/Throwable;Ljava/util/Map;)V
public fun close ()V
public fun debug (Z)V
public fun evaluateFlags (Ljava/lang/String;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public fun evaluateFlags (Ljava/lang/String;Lcom/posthog/server/PostHogEvaluateFlagsOptions;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public fun evaluateFlags (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/List;ZZ)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public fun flush ()V
public fun getFeatureFlag (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
public fun getFeatureFlag (Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogFeatureFlagOptions;)Ljava/lang/Object;
Expand Down Expand Up @@ -43,9 +46,10 @@ public final class com/posthog/server/PostHog$Companion {

public final class com/posthog/server/PostHogCaptureOptions {
public static final field Companion Lcom/posthog/server/PostHogCaptureOptions$Companion;
public synthetic fun <init> (Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;ZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;ZLcom/posthog/server/PostHogFeatureFlagEvaluations;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public static final fun builder ()Lcom/posthog/server/PostHogCaptureOptions$Builder;
public final fun getAppendFeatureFlags ()Z
public final fun getFlags ()Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public final fun getGroups ()Ljava/util/Map;
public final fun getProperties ()Ljava/util/Map;
public final fun getTimestamp ()Ljava/util/Date;
Expand All @@ -57,7 +61,9 @@ public final class com/posthog/server/PostHogCaptureOptions$Builder {
public fun <init> ()V
public final fun appendFeatureFlags (Z)Lcom/posthog/server/PostHogCaptureOptions$Builder;
public final fun build ()Lcom/posthog/server/PostHogCaptureOptions;
public final fun flags (Lcom/posthog/server/PostHogFeatureFlagEvaluations;)Lcom/posthog/server/PostHogCaptureOptions$Builder;
public final fun getAppendFeatureFlags ()Z
public final fun getFlags ()Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public final fun getGroups ()Ljava/util/Map;
public final fun getProperties ()Ljava/util/Map;
public final fun getTimestamp ()Ljava/util/Date;
Expand All @@ -68,6 +74,7 @@ public final class com/posthog/server/PostHogCaptureOptions$Builder {
public final fun properties (Ljava/util/Map;)Lcom/posthog/server/PostHogCaptureOptions$Builder;
public final fun property (Ljava/lang/String;Ljava/lang/Object;)Lcom/posthog/server/PostHogCaptureOptions$Builder;
public final fun setAppendFeatureFlags (Z)V
public final fun setFlags (Lcom/posthog/server/PostHogFeatureFlagEvaluations;)V
public final fun setGroups (Ljava/util/Map;)V
public final fun setProperties (Ljava/util/Map;)V
public final fun setTimestamp (Ljava/util/Date;)V
Expand Down Expand Up @@ -175,6 +182,67 @@ public final class com/posthog/server/PostHogConfig$Companion {
public final fun builder (Ljava/lang/String;)Lcom/posthog/server/PostHogConfig$Builder;
}

public final class com/posthog/server/PostHogEvaluateFlagsOptions {
public static final field Companion Lcom/posthog/server/PostHogEvaluateFlagsOptions$Companion;
public synthetic fun <init> (Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/List;ZZLkotlin/jvm/internal/DefaultConstructorMarker;)V
public static final fun builder ()Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun getDisableGeoip ()Z
public final fun getFlagKeys ()Ljava/util/List;
public final fun getGroupProperties ()Ljava/util/Map;
public final fun getGroups ()Ljava/util/Map;
public final fun getOnlyEvaluateLocally ()Z
public final fun getPersonProperties ()Ljava/util/Map;
}

public final class com/posthog/server/PostHogEvaluateFlagsOptions$Builder {
public fun <init> ()V
public final fun build ()Lcom/posthog/server/PostHogEvaluateFlagsOptions;
public final fun disableGeoip (Z)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun flagKeys (Ljava/util/List;)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun getDisableGeoip ()Z
public final fun getFlagKeys ()Ljava/util/List;
public final fun getGroupProperties ()Ljava/util/Map;
public final fun getGroups ()Ljava/util/Map;
public final fun getOnlyEvaluateLocally ()Z
public final fun getPersonProperties ()Ljava/util/Map;
public final fun group (Ljava/lang/String;Ljava/lang/String;)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun groupProperties (Ljava/util/Map;)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun groupProperty (Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun groups (Ljava/util/Map;)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun onlyEvaluateLocally (Z)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun personProperties (Ljava/util/Map;)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun personProperty (Ljava/lang/String;Ljava/lang/Object;)Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
public final fun setDisableGeoip (Z)V
public final fun setFlagKeys (Ljava/util/List;)V
public final fun setGroupProperties (Ljava/util/Map;)V
public final fun setGroups (Ljava/util/Map;)V
public final fun setOnlyEvaluateLocally (Z)V
public final fun setPersonProperties (Ljava/util/Map;)V
}

public final class com/posthog/server/PostHogEvaluateFlagsOptions$Companion {
public final fun builder ()Lcom/posthog/server/PostHogEvaluateFlagsOptions$Builder;
}

public final class com/posthog/server/PostHogFeatureFlagEvaluations {
public static final field Companion Lcom/posthog/server/PostHogFeatureFlagEvaluations$Companion;
public final fun getDefinitionsLoadedAt ()Ljava/lang/Long;
public final fun getDistinctId ()Ljava/lang/String;
public final fun getEvaluatedAt ()Ljava/lang/Long;
public final fun getFlag (Ljava/lang/String;)Ljava/lang/Object;
public final fun getFlagPayload (Ljava/lang/String;)Ljava/lang/String;
public final fun getFlagPayloadAs (Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
public final fun getKeys ()Ljava/util/List;
public final fun getRequestId ()Ljava/lang/String;
public final fun isEnabled (Ljava/lang/String;)Z
public final fun only (Ljava/util/Collection;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public final fun only ([Ljava/lang/String;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public final fun onlyAccessed ()Lcom/posthog/server/PostHogFeatureFlagEvaluations;
}

public final class com/posthog/server/PostHogFeatureFlagEvaluations$Companion {
}

public final class com/posthog/server/PostHogFeatureFlagOptions {
public static final field Companion Lcom/posthog/server/PostHogFeatureFlagOptions$Companion;
public synthetic fun <init> (Ljava/lang/Object;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down Expand Up @@ -247,13 +315,16 @@ public abstract interface class com/posthog/server/PostHogInterface {
public abstract fun alias (Ljava/lang/String;Ljava/lang/String;)V
public abstract fun capture (Ljava/lang/String;Ljava/lang/String;)V
public abstract fun capture (Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogCaptureOptions;)V
public abstract synthetic fun capture (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;Z)V
public abstract synthetic fun capture (Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;ZLcom/posthog/server/PostHogFeatureFlagEvaluations;)V
public abstract fun captureException (Ljava/lang/Throwable;)V
public abstract fun captureException (Ljava/lang/Throwable;Ljava/lang/String;)V
public abstract fun captureException (Ljava/lang/Throwable;Ljava/lang/String;Ljava/util/Map;)V
public abstract fun captureException (Ljava/lang/Throwable;Ljava/util/Map;)V
public abstract fun close ()V
public abstract fun debug (Z)V
public abstract fun evaluateFlags (Ljava/lang/String;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public abstract fun evaluateFlags (Ljava/lang/String;Lcom/posthog/server/PostHogEvaluateFlagsOptions;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public abstract synthetic fun evaluateFlags (Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/List;ZZ)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public abstract fun flush ()V
public abstract fun getFeatureFlag (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
public abstract fun getFeatureFlag (Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogFeatureFlagOptions;)Ljava/lang/Object;
Expand Down Expand Up @@ -282,11 +353,14 @@ public abstract interface class com/posthog/server/PostHogInterface {
public final class com/posthog/server/PostHogInterface$DefaultImpls {
public static fun capture (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;)V
public static fun capture (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogCaptureOptions;)V
public static synthetic fun capture$default (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;ZILjava/lang/Object;)V
public static synthetic fun capture$default (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/Date;ZLcom/posthog/server/PostHogFeatureFlagEvaluations;ILjava/lang/Object;)V
public static fun captureException (Lcom/posthog/server/PostHogInterface;Ljava/lang/Throwable;)V
public static fun captureException (Lcom/posthog/server/PostHogInterface;Ljava/lang/Throwable;Ljava/lang/String;)V
public static fun captureException (Lcom/posthog/server/PostHogInterface;Ljava/lang/Throwable;Ljava/util/Map;)V
public static synthetic fun captureException$default (Lcom/posthog/server/PostHogInterface;Ljava/lang/Throwable;Ljava/lang/String;Ljava/util/Map;ILjava/lang/Object;)V
public static fun evaluateFlags (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public static fun evaluateFlags (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Lcom/posthog/server/PostHogEvaluateFlagsOptions;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public static synthetic fun evaluateFlags$default (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/util/Map;Ljava/util/Map;Ljava/util/Map;Ljava/util/List;ZZILjava/lang/Object;)Lcom/posthog/server/PostHogFeatureFlagEvaluations;
public static fun getFeatureFlag (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;
public static fun getFeatureFlag (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Lcom/posthog/server/PostHogFeatureFlagOptions;)Ljava/lang/Object;
public static fun getFeatureFlag (Lcom/posthog/server/PostHogInterface;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
Expand Down
Loading
Loading