---
title: "GET /api/projects/{project_id}/experiments/{id}/health_inputs/"
method: GET
path: "/api/projects/{project_id}/experiments/{id}/health_inputs/"
tags: ["experiments"]
---

# GET /api/projects/{project_id}/experiments/{id}/health_inputs/

`GET /api/projects/{project_id}/experiments/{id}/health_inputs/`

## Request

- Base URL: `https://us.posthog.com`
- URL: `https://us.posthog.com/api/projects/{project_id}/experiments/{id}/health_inputs/`
- Auth: HTTP bearer

Staff only. The inputs that the health checks read for this reader, to debug why a finding shows or not:
the context of the checks in `health`, the exposure query's answer that the exposure checks read, and facts
about the project from the setup context's providers (the team's experiment defaults and which SDKs call
flags). The exposure answer comes from the cache. When it is missing or stale, a calculation starts in the
background and `exposures.status` says so.

## Path parameters

- `id` integer, required
- `project_id` string, required

## Response `200`

- ExperimentHealthInputs
  - `is_launched` boolean, required: Whether the experiment has a start date.
  - `is_running` boolean, required: Whether the experiment is launched and not ended.
  - `has_ended` boolean, required: Whether the experiment has an end date.
  - `is_paused` boolean, required: Whether the experiment is paused.
  - `archived` boolean, required: Whether the experiment is archived.
  - `baseline_variant_key` string, nullable, required: The baseline set in the experiment's settings. Null when unset.
  - `excluded_variant_keys` string[], required: The variants the analysis leaves out of the results. The forced-variant check ignores pins to them.
  - `primary_metric_count` integer, required: Single-use primary metrics plus shared metrics linked as primary.
  - `secondary_metric_count` integer, required: Single-use secondary metrics plus shared metrics linked as secondary.
  - `flag` ExperimentHealthInputsFlag, required
    - `active` boolean, required: Whether the flag is enabled.
    - `deleted` boolean, required: Whether the flag is deleted.
    - `release_conditions` ExperimentHealthInputsReleaseCondition[], required: The flag's release conditions, in evaluation order.
      - `number` integer, required: The condition's position in the flag, from 1, as the flag page labels it ('Set 2').
      - `rollout_percentage` number, double, nullable, required: The condition's rollout, in percent. Null when the flag stores no number.
      - `property_count` integer, nullable, required: The number of property filters. Null when the flag stores no list.
      - `reachable` boolean, required: Whether the condition can serve a request. A condition after one that matches everyone never does.
      - `pinned_variant` string, nullable, required: The variant that the condition's override serves. Null when the condition is not reachable, has no override, or its override names no variant of the flag.
    - `variants` ExperimentHealthInputsVariant[], required: The flag's variants and their split.
      - `key` string, nullable, required: The variant key. Null when the flag stores no string key.
      - `rollout_percentage` number, double, nullable, required: The variant's share of the split, in percent. Null when the flag stores no number.
    - `split_text` string, required: The split as text, in the form of a change's before and after, such as 'control 50%, test 50%'.
  - `flag_last_called_at` string, date-time, nullable, required: The flag's latest recorded call, which a periodic sync of the flag call events sets. Null when the experiment has no flag, or the flag has no recorded call.
  - `flag_called` boolean, nullable, required: Whether PostHog has recorded any call of the flag. The flag traffic check reads it on a draft. Null when the experiment has no flag, or the organization's flag calls are stored where the checks can't read them.
  - `flag_called_during_run` boolean, nullable, required: Whether PostHog has recorded a call of the flag between launch and the end, or until now. The zero exposures check reads it to say whether the flag is called. Null before launch, after a latest call that came after the end, or when the organization's flag calls can't be read.
  - `exposure_events` ExperimentHealthInputsExposureEvents, required
    - `custom_event` string, nullable, required: The event the exposure criteria count in place of the flag calls. Null for flag calls or an action.
    - `required_flag_key` string, nullable, required: The flag key the exposure query requires on the flag call events. Null for a custom event or an action.
    - `variant_property` string, required: The event property that holds the variant.
    - `activation` string, nullable, required: The event, or the action's name, that has to follow a user's flag call before the user counts. Null without an activation.
  - `events_received` object, required: Whether the project has received each event that the metrics and the exposure criteria name, by event name. A name that ingestion keeps no record of is absent.
  - `flag_history` ExperimentHealthInputsFlagHistory, required
    - `checked` boolean, required: Whether the changes were compared with the exposures. False when not_checked_reason is set.
    - `not_checked_reason` string, nullable, required: Why the changes were not compared with the exposures: 'no_history_access', 'no_query_access', 'exposure_filters', 'exposure_action' or 'exposure_criteria'. Null when they were.
    - `launched_at` string, date-time, required: When the experiment launched.
    - `team_timezone` string, required: The project's time zone, which the findings use for times.
    - `changes` ExperimentHealthInputsFlagChange[], required: Every change since launch that can move exposed people, of every kind, in time order. A bucketing change is one per setting and save. A rollout change alone is no release-condition change. Empty for 'no_history_access', which does not read them.
      - `kind` 'split' | 'bucketing' | 'release_conditions', required: * `split` - Split * `bucketing` - Bucketing * `release_conditions` - Release-condition
      - `changed_at` string, date-time, required: When the flag changed.
      - `changed` string, required: What changed, as the staff view names it, such as 'Split' or 'Key'.
      - `before` string, required: The value before the change as text, such as 'control 50%, test 50%' or 'device_id'. 'none' when unset.
      - `after` string, required: The value after the change, in the same form.
      - `counted` boolean, required: Whether the checks count this change: every change counts from the first change, of any kind, with an exposure before it, or an unknown answer. False for every change when not checked.
    - `exposed_before_first` boolean, nullable, required: Whether anyone was exposed before the first counted change. Null when unknown or not checked.
    - `exposed_between` ExperimentHealthInputsExposedBetween[], required: One entry for each kind of change with a counted change, in the order of the kinds.
      - `kind` 'split' | 'bucketing' | 'release_conditions', required: * `split` - Split * `bucketing` - Bucketing * `release_conditions` - Release-condition
      - `question` string, required: What was asked, as the staff view names it.
      - `exposed` boolean, nullable, required: Whether anyone was exposed between the first and the last counted change of this kind. Asked only when the last sets back what the first changed. Null when not asked or unknown.
  - `condition_set_traffic_status` 'read' | 'not_needed' | 'no_query_access' | 'denied_properties' | 'no_flag_version' | 'unknown', required: * `read` - Read * `not_needed` - Not Needed * `no_query_access` - No Query Access * `denied_properties` - Denied Properties * `no_flag_version` - No Flag Version * `unknown` - Unknown
  - `condition_set_traffic` ExperimentHealthInputsConditionSetTraffic, required
    - `since` string, date-time, required: The start of the window: the latest of launch, the flag's last save and 7 days ago.
    - `team_timezone` string, required: The project's time zone, which the finding uses for times.
    - `people_by_set` ExperimentHealthInputsConditionSetPeople[], required: People by the release condition that served their latest call of the flag's version.
      - `condition_set` integer, required: The number of the release condition, from 1.
      - `people` integer, required: The people whose latest call this condition served.
    - `calls` integer, required: The flag's calls in the window, of any flag version.
    - `remotely_evaluated_calls` integer, required: The calls that the flag service evaluated. Only those name a condition set. Local evaluation in a server SDK and a bootstrapped value name none.
    - `people_assigned_outside` integer, required: The people who got a variant from a call without a flag version that is no local evaluation in a server SDK, from an hour after the start of the window: a bootstrap or the caller's own assignment. With a 0% rollout, 10 or more of them turn `running_but_no_rollout` into `assigned_outside_flag_service`.
  - `reader_access` ExperimentHealthInputsReaderAccess, required
    - `can_read_flag_history` boolean, required: Whether the reader may read the flag's history, which the flag-change checks need.
    - `can_query_events` boolean, required: Whether the reader may query events, which the flag-change and forced-variant checks need.
    - `denied_event_properties` string[], required: Event properties the reader is denied. The forced-variant and release-condition checks skip their scan when one of them is a flag call property it reads.
  - `exposures` ExperimentHealthInputsExposures, required
    - `status` 'ready' | 'stale' | 'calculating' | 'not_launched' | 'no_query_access' | 'failed', required: * `ready` - Ready * `stale` - Stale * `calculating` - Calculating * `not_launched` - Not Launched * `no_query_access` - No Query Access * `failed` - Failed
    - `computed_at` string, date-time, nullable, required: When the answer was computed.
    - `totals` ExperimentHealthInputsExposureTotals, required
      - `total_exposures` object, required: Exposed people by variant. '$multiple' counts the people exposed to more than one variant.
      - `multiple_variant_handling` string, required: How the analysis treats people in several variants: 'exclude' or 'first_seen'.
      - `sample_ratio_mismatch_p_value` number, double, nullable, required: The p-value of the sample ratio test. Null when there was too little data.
      - `hours_since_launch` number, double, nullable, required: Hours from launch to the computation of the answer, as the checks read them.
    - `findings` ExperimentHealthFinding[], required: The findings of the exposure checks on this answer: zero exposures, SRM and bias risk.
      - `code` 'flag_off_while_running' | 'variant_shipped_while_running' | 'flag_live_after_end' | 'flag_live_before_launch' | 'bias_risk_multiple_excluded' | 'multiple_variants_share' | 'no_metric' | 'metric_event_not_ingested' | 'exposure_criteria_cannot_match' | 'srm' | 'zero_exposures' | 'forced_variant_release_condition' | 'flag_variants_mismatch' | 'split_changed_mid_run' | 'bucketing_changed_mid_run' | 'release_conditions_changed_mid_run' | 'new_flag_no_traffic' | 'early_significance', required: * `flag_off_while_running` - Flag Off While Running * `variant_shipped_while_running` - Variant Shipped While Running * `flag_live_after_end` - Flag Live After End * `flag_live_before_launch` - Flag Live Before Launch * `bias_risk_multiple_excluded` - Bias Risk Multiple Excluded * `multiple_variants_share` - Multiple Variants Share * `no_metric` - No Metric * `metric_event_not_ingested` - Metric Event Not Ingested * `exposure_criteria_cannot_match` - Exposure Criteria Cannot Match * `srm` - Sample Ratio Mismatch * `zero_exposures` - Zero Exposures * `forced_variant_release_condition` - Forced Variant Release Condition * `flag_variants_mismatch` - Flag Variants Mismatch * `split_changed_mid_run` - Split Changed Mid Run * `bucketing_changed_mid_run` - Bucketing Changed Mid Run * `release_conditions_changed_mid_run` - Release Conditions Changed Mid Run * `new_flag_no_traffic` - New Flag No Traffic * `early_significance` - Early Significance
      - `subcode` string, nullable, required: The case within the code, when a code covers several, for example 'running_but_no_rollout' within 'flag_off_while_running'. Null when the code has one case.
      - `severity` 'critical' | 'warning' | 'info', required: * `critical` - Critical severity * `warning` - Warning severity * `info` - Info severity
      - `title` string, required: One-line summary of the problem.
      - `detail` string, required: What is wrong, what it does to the experiment, and how to fix it.
      - `evidence` object, required: The values behind the finding, such as the key of a shipped variant or the share of users exposed to multiple variants. The keys depend on the code.
      - `actions` ExperimentHealthFindingActionKindEnum[], required: The actions that fix the problem, in order of preference, for example 'open_feature_flag' or 'add_primary_metric'.
      - `diagnostic_ref` string, nullable, required: The id of the matching diagnostic in the diagnosing-experiment-health skill, for example 'A5'. Null when the skill has none.
    - `error` string, nullable, required: Why the query or its last background calculation failed. Set for 'failed', and for 'stale' when the recalculation failed.
  - `project` ExperimentHealthInputsProject, required
    - `team_defaults` ExperimentSetupTeamDefaultsSection, required
      - `status` 'ok' | 'skipped' | 'timed_out' | 'error', required: * `ok` - Ok * `skipped` - Skipped * `timed_out` - Timed Out * `error` - Error
      - `data` ExperimentSetupTeamDefaults, required
        - `stats_method` string, nullable, required: Default statistical method for new experiments: 'bayesian' or 'frequentist'.
        - `confidence_level` number, double, nullable, required: Default confidence level for new experiments, for example 0.95. Null when unset.
        - `minimum_detectable_effect` integer, nullable, required: The team's default minimum detectable effect, as a percentage. Null when the team has not set one; product_default_minimum_detectable_effect applies then.
        - `product_default_minimum_detectable_effect` integer, required: The minimum detectable effect, as a percentage, that applies when the team has no default.
        - `product_default_stats_method` string, required: The statistical method that applies when the team has no default.
        - `product_default_confidence_level` number, double, required: The confidence level that applies when the team has no default. Both methods use the same one.
        - `only_count_matured_users` boolean, required: Default for counting only users whose metric window has fully passed.
        - `cuped_enabled` boolean, required: Default for CUPED variance reduction on new experiments.
        - `sequential_testing_enabled` boolean, required: Default for sequential testing. Applies only to the frequentist method.
        - `flags_persistence_default` boolean, required: Default for persisting flag values across authentication steps on new flags. It becomes the flag's ensure_experience_continuity.
        - `test_account_filter_count` integer, required: How many filters the team uses to identify internal and test users.
        - `new_experiments_filter_test_accounts` boolean, required: A new experiment filters test accounts this way unless its own exposure criteria say otherwise. It does not follow the project's insight default.
        - `default_exposure_event` string, required: The exposure event a new experiment launched now counts by default: '$experiment_exposure' or '$feature_flag_called'.
    - `sdk_profile` ExperimentSetupSdkProfileSection, required
      - `status` 'ok' | 'skipped' | 'timed_out' | 'error', required: * `ok` - Ok * `skipped` - Skipped * `timed_out` - Timed Out * `error` - Error
      - `data` ExperimentSetupSdkProfile, required
        - `window_days` integer, required: Days of flag calls read, ending now.
        - `source_event` string, required: The event read: '$experiment_exposure' when the project receives it, otherwise '$feature_flag_called'. Only one is read, because one copies the other, and only multivariate responses count either way. This says what the project's events carry today, so it can differ from team_defaults.default_exposure_event, which says what a new experiment would count.
        - `computed_at` string, date-time, required: When the numbers were computed. They are cached for hours.
        - `libs` ExperimentSetupSdkLib[], required: One row per SDK, most calls first.
          - `lib` string, nullable, required: The $lib value of the SDK, for example 'web'.
          - `category` 'web' | 'mobile' | 'server' | 'other', required: * `web` - Web * `mobile` - Mobile * `server` - Server * `other` - Other
          - `calls` integer, required: Multivariate flag calls this SDK sent in the window.
          - `distinct_ids` integer, required: Distinct ids that sent those calls.
          - `device_id_share` number, double, required: Share of calls that carry a $device_id. 0 when this SDK never sends one, as server SDKs don't.
          - `locally_evaluated_share` number, double, nullable, required: Share of calls evaluated locally in the SDK instead of by the flags service. Null when no call from this SDK reported it, as the web SDK doesn't.
          - `anonymous_share` number, double, nullable, required: Share of distinct ids that were anonymous, among those that report whether they are identified. Null when no call from this SDK reported it.
        - `libs_truncated` boolean, required: True when more SDKs sent flag calls than libs lists.
        - `flags_seen` integer, required: Distinct multivariate flag keys called in the window.
        - `flags_evaluated_on_server_and_web` integer, required: How many of those flag keys were called by both a server SDK and the web SDK.
        - `evaluated_on_server_and_web` boolean, required: True when at least one flag key was called by both a server SDK and the web SDK. The same flag decided on the server and read in the browser can bucket one user into two variants.
        - `libs_on_any_event` ExperimentSetupLibActivity[], nullable, required: Up to 10 SDKs seen on any event over the last day, most events first. Set only when libs is empty, so a project creating its first experiment still says which platforms it sends from. Null when flag calls exist, and null when this extra read timed out.
          - `lib` string, nullable, required: The $lib value of the SDK, for example 'web'.
          - `category` 'web' | 'mobile' | 'server' | 'other', required: * `web` - Web * `mobile` - Mobile * `server` - Server * `other` - Other
          - `events` integer, required: Events this SDK sent in the window, of any kind.
          - `distinct_ids` integer, required: Distinct ids that sent those events.
        - `libs_on_any_event_truncated` boolean, required: True when more SDKs sent events than libs_on_any_event lists. False when it is null.

## Changes

> 53 revisions in range; 1 not diffed.

- **2026-10-23** `993f70ab941b`: 1 warning
  - added the new `early_significance` enum value to the `exposures/allOf[#/components/schemas/ExperimentHealthInputsExposures]/findings/items/code/allOf[#/components/schemas/ExperimentHealthFindingCodeEnum]/` response property for the response status `200`
- **2026-10-22** `0ca22e1eb92b`: 5 info
  - added the required property `events_received` to the response with the `200` status
  - added the required property `exposure_events` to the response with the `200` status
  - added the required property `flag_called` to the response with the `200` status
  - added the required property `flag_called_during_run` to the response with the `200` status
  - …1 more
- **2026-10-21** `e263ffc38ef5`: 2 warning
  - added the new `exposure_criteria_cannot_match` enum value to the `exposures/allOf[#/components/schemas/ExperimentHealthInputsExposures]/findings/items/code/allOf[#/components/schemas/ExperimentHealthFindingCodeEnum]/` response property for the response status `200`
  - added the new `metric_event_not_ingested` enum value to the `exposures/allOf[#/components/schemas/ExperimentHealthInputsExposures]/findings/items/code/allOf[#/components/schemas/ExperimentHealthFindingCodeEnum]/` response property for the response status `200`
- …earlier changes not shown

[Operation history](https://skmtc.dev/posthog/apis/posthog-api/changes/api/projects/:project_id/experiments/:id/health_inputs/get.md)

---

[API](https://skmtc.dev/posthog/apis/posthog-api.md) · [All operations](https://skmtc.dev/posthog/apis/posthog-api/llms.txt) · [OpenAPI document](https://skmtc.dev/posthog/apis/posthog-api/revisions/993f70ab941b?raw)
