Flags – the feature flags evaluation API endpoint
The flags
endpoint is used to evaluate feature flags for a given distinct_id
. This means it is the main endpoint not only for feature flags, but also experimentation, early access features, and survey display conditions.
It is a POST-only public endpoint that uses your project API key and does not return any sensitive data from your PostHog instance.
Note: Make sure to send API requests to the correct domain. These are
https://us.i.posthog.com
for US Cloud,https://eu.i.posthog.com
for EU Cloud, and your self-hosted domain for self-hosted instances. Confirm yours by checking your URL from your PostHog instance.
There are 3 steps to implement feature flags using the PostHog API:
Step 1: Evaluate the feature flag value using flags
flags
is the endpoint used to determine if a given flag is enabled for a certain user or not.
Request
Note: The
groups
key is only required for group-based feature flags. If you use it, replacegroup_type
andgroup_id
with the values for your group such ascompany: "Twitter"
.
Using evaluation environment tags and runtime filtering without SDKs
When making direct API calls to the /flags
endpoint, you can control which flags are evaluated using evaluation environment tags and runtime filtering.
Evaluation environments
To filter flags by evaluation environment, include the evaluation_environments
field in your request body:
Only flags where at least one evaluation tag matches (or flags with no tags at all) will be returned. For example:
- Flag with evaluation environment tags
["production", "api", "backend"]
+ request with["production", "web"]
= ✅ Flag evaluates ("production" matches) - Flag with evaluation environment tags
["staging", "api"]
+ request with["production", "web"]
= ❌ Flag doesn't evaluate (no tags match) - Flag with evaluation environment tags
["web", "mobile"]
+ request with["production", "web"]
= ✅ Flag evaluates ("web" matches) - Flag with no evaluation environment tags = ✅ Always evaluates (backward compatibility)
Runtime detection
Evaluation runtime (server vs. client) is automatically detected based on your request headers and user-agent. This determines which flags are available based on their runtime setting (server-only, client-only, or all).
How runtime is detected:
User-Agent patterns - The system analyzes the User-Agent header:
- Client-side patterns:
Mozilla/
,Chrome/
,Safari/
,Firefox/
,Edge/
(browsers), or mobile SDKs likeposthog-android/
,posthog-ios/
,posthog-react-native/
,posthog-flutter/
- Server-side patterns:
posthog-python/
,posthog-ruby/
,posthog-php/
,posthog-java/
,posthog-go/
,posthog-node/
,posthog-dotnet/
,posthog-elixir/
,python-requests/
,curl/
- Client-side patterns:
Browser-specific headers - Presence of these headers indicates client-side:
Origin
headerReferer
headerSec-Fetch-Mode
headerSec-Fetch-Site
header
Default behavior - If runtime can't be determined, the system includes flags with no runtime requirement and those set to "all"
Examples of runtime detection:
Combining evaluation environment tags and runtime filtering
Both features work together as sequential filters:
This allows precise control over which flags are evaluated in different contexts, helping optimize costs and improve security by ensuring flags only evaluate where intended.
Response
The response varies depending on whether you include the config=true
query parameter:
Basic response (/flags?v=2
)
Use this endpoint when you only need to evaluate feature flags. It returns a response with just the flag evaluation results:
Full response with configuration (/flags?v=2&config=true
)
Use this endpoint when you need both feature flag evaluation and PostHog configuration information (useful for client-side SDKs that need to initialize PostHog):
Note:
errorsWhileComputingFlags
will returntrue
if we didn't manage to compute some flags (for example, if there's an ongoing incident involving flag evaluation).This enables partial updates to currently active flags in your clients.
Quota limiting
If your organization exceeds its feature flag quota, the /flags
endpoint will return a modified response with quotaLimited
.
For basic response (/flags?v=2
):
For full response with configuration (/flags?v=2&config=true
):
When you receive a response with quotaLimited
containing "feature_flags"
, it means:
- Your feature flag evaluations have been temporarily paused because you've exceeded your feature flag quota
- If you want to continue evaluating feature flags, you can increase your quota in your billing settings under Feature flags & Experiments or contact support
Step 2: Include feature flag information when capturing events
If you want use your feature flag to breakdown or filter events in your insights, you'll need to include feature flag information in those events. This ensures that the feature flag value is attributed correctly to the event.
Note: This step is only required for events captured using our server-side SDKs or API.
To do this, include the $feature/feature_flag_name
property in your event:
Step 3: Send a $feature_flag_called
event
To track usage of your feature flag and view related analytics in PostHog, submit the $feature_flag_called
event whenever you check a feature flag value in your code.
You need to include two properties with this event:
$feature_flag_response
: This is the name of the variant the user has been assigned to e.g., "control" or "test"$feature_flag
: This is the key of the feature flag in your experiment.
Advanced: Overriding server properties
Sometimes, you may want to evaluate feature flags using person properties, groups, or group properties that haven't been ingested yet, or were set incorrectly earlier.
You can provide properties to evaluate the flag with by using the person properties
, groups
, and group properties
arguments. PostHog will then use these values to evaluate the flag, instead of any properties currently stored on your PostHog server.
For example:
Overriding GeoIP properties
By default, a user's GeoIP properties are set using the IP address they use to capture events on the frontend. You may want to override the these properties when evaluating feature flags. A common reason to do this is when you're not using PostHog on your frontend, so the user has no GeoIP properties.
To override the GeoIP properties used to evaluate a feature flag, provide an IP address in the HTTP_X_FORWARDED_FOR
when making your /flags
request:
The list of properties that this overrides:
$geoip_city_name
$geoip_country_name
$geoip_country_code
$geoip_continent_name
$geoip_continent_code
$geoip_postal_code
$geoip_time_zone