Experiments-2

For instructions on how to authenticate to use this endpoint, see API overview.

Endpoints

GET
POST
POST
POST
GET
GET
GET
GET

Retrieve experiments timeseries results

Mixin for ViewSets to handle ApprovalRequired exceptions from decorated serializers.

This mixin intercepts ApprovalRequired exceptions raised by the @approval_gate decorator on serializer methods and converts them into proper HTTP 409 Conflict responses with change request details.

Required API key scopes

experiment:read

Path parameters

  • id
    integer

Query parameters

  • fingerprint
    string
  • metric_uuid
    string

Example request

GET /api/projects/:project_id/experiments/:id/timeseries_results
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/experiments/:id/timeseries_results/

Example response

Status 200 No response body

Create experiments unarchive

Unarchive an archived experiment.

Restores the experiment to the default list view. Returns 400 if the experiment is not currently archived.

Required API key scopes

experiment:write

Path parameters

  • id
    integer

Response


Example request

POST /api/projects/:project_id/experiments/:id/unarchive
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/experiments/:id/unarchive/

Example response

Status 200
RESPONSE
{
"id": 0,
"name": "string",
"description": "string",
"start_date": "2019-08-24T14:15:22Z",
"end_date": "2019-08-24T14:15:22Z",
"feature_flag_key": "string",
"feature_flag": {
"id": 0,
"team_id": 0,
"name": "string",
"key": "string",
"filters": {},
"deleted": true,
"active": true,
"ensure_experience_continuity": true,
"version": -2147483648,
"evaluation_runtime": "server",
"bucketing_identifier": "distinct_id",
"evaluation_contexts": [
"string"
]
},
"holdout": {
"id": 0,
"name": "string",
"description": "string",
"filters": null,
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"user_access_level": "string"
},
"holdout_id": 0,
"exposure_cohort": 0,
"parameters": {
"excluded_variants": null,
"feature_flag_variants": null,
"minimum_detectable_effect": null,
"rollout_percentage": null,
"variant_notes": null
},
"running_time_calculation": {
"exposure_estimate_config": null,
"minimum_detectable_effect": null,
"recommended_running_time": null,
"recommended_sample_size": null
},
"excluded_variants": [
"string"
],
"secondary_metrics": null,
"saved_metrics": [
{
"id": 0,
"experiment": 0,
"saved_metric": 0,
"metadata": null,
"created_at": "2019-08-24T14:15:22Z",
"query": null,
"name": "string"
}
],
"saved_metrics_ids": [
null
],
"filters": null,
"archived": false,
"deleted": true,
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "web",
"exposure_criteria": {
"exposure_config": null,
"filterTestAccounts": null,
"multiple_variant_handling": null
},
"metrics": [
{
"completion_event": null,
"conversion_window": null,
"denominator": null,
"denominator_outlier_handling": null,
"goal": null,
"ignore_zeros": null,
"kind": "ExperimentMetric",
"lower_bound_percentile": null,
"metric_type": "funnel",
"name": null,
"numerator": null,
"numerator_outlier_handling": null,
"retention_window_end": null,
"retention_window_start": null,
"retention_window_unit": null,
"series": null,
"source": null,
"start_event": null,
"start_handling": null,
"threshold": null,
"upper_bound_percentile": null,
"uuid": null
}
],
"metrics_secondary": [
{
"completion_event": null,
"conversion_window": null,
"denominator": null,
"denominator_outlier_handling": null,
"goal": null,
"ignore_zeros": null,
"kind": "ExperimentMetric",
"lower_bound_percentile": null,
"metric_type": "funnel",
"name": null,
"numerator": null,
"numerator_outlier_handling": null,
"retention_window_end": null,
"retention_window_start": null,
"retention_window_unit": null,
"series": null,
"source": null,
"start_event": null,
"start_handling": null,
"threshold": null,
"upper_bound_percentile": null,
"uuid": null
}
],
"stats_config": null,
"scheduling_config": null,
"allow_unknown_events": false,
"_create_in_folder": "string",
"conclusion": "won",
"conclusion_comment": "string",
"primary_metrics_ordered_uuids": null,
"secondary_metrics_ordered_uuids": null,
"only_count_matured_users": true,
"update_feature_flag_params": false,
"status": "draft",
"is_legacy": true,
"user_access_level": "string"
}

Create experiments calculate running time

Estimate the recommended sample size and running time for an experiment.

Pure statistical calculation — does not read or write any experiment. Pass the metric type, a minimum detectable effect, and either a baseline value or raw baseline statistics. When exposure_rate_per_day is provided, the response also includes the estimated running time in days.

Required API key scopes

experiment:read

Request parameters

  • metric_type
  • minimum_detectable_effect
    number
  • number_of_variants
    integer
    Default: 2
  • exposure_rate_per_day
    numbernull
  • baseline_value
    numbernull
  • variance
    numbernull
  • baseline_stats

Response


Example request

POST /api/projects/:project_id/experiments/calculate_running_time
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/experiments/calculate_running_time/\
-d metric_type=undefined,\
-d minimum_detectable_effect="number"

Example response

Status 200
RESPONSE
{
"baseline_value": 0,
"variance": 0,
"recommended_sample_size": 0,
"recommended_running_time_days": 0
}

Create experiments create from prompt

Create an experiment that compares N versions of an LLM prompt using a metric template.

The user picks 2+ versions of an existing LLMPrompt and 1+ metric templates (cost / latency / eval_pass_rate). The endpoint builds the matching variants (control + test-N, each named after its prompt version) and attaches one metric per selected template, each scoped to the prompt's $ai_prompt_name. Resulting experiment is in draft state.

Required API key scopes

experiment:writellm_prompt:read

Request parameters

  • prompt_name
    string
  • versions
    array
  • templates
    Click to open
    array
  • name
    string
  • feature_flag_key
    string
  • description
    string

Response


Example request

POST /api/projects/:project_id/experiments/create_from_prompt
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/experiments/create_from_prompt/\
-d prompt_name="string",\
-d versions="array",\
-d templates="array"

Example response

Status 200
RESPONSE
{
"id": 0,
"name": "string",
"description": "string",
"start_date": "2019-08-24T14:15:22Z",
"end_date": "2019-08-24T14:15:22Z",
"feature_flag_key": "string",
"feature_flag": {
"id": 0,
"team_id": 0,
"name": "string",
"key": "string",
"filters": {},
"deleted": true,
"active": true,
"ensure_experience_continuity": true,
"version": -2147483648,
"evaluation_runtime": "server",
"bucketing_identifier": "distinct_id",
"evaluation_contexts": [
"string"
]
},
"holdout": {
"id": 0,
"name": "string",
"description": "string",
"filters": null,
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"user_access_level": "string"
},
"holdout_id": 0,
"exposure_cohort": 0,
"parameters": {
"excluded_variants": null,
"feature_flag_variants": null,
"minimum_detectable_effect": null,
"rollout_percentage": null,
"variant_notes": null
},
"running_time_calculation": {
"exposure_estimate_config": null,
"minimum_detectable_effect": null,
"recommended_running_time": null,
"recommended_sample_size": null
},
"excluded_variants": [
"string"
],
"secondary_metrics": null,
"saved_metrics": [
{
"id": 0,
"experiment": 0,
"saved_metric": 0,
"metadata": null,
"created_at": "2019-08-24T14:15:22Z",
"query": null,
"name": "string"
}
],
"saved_metrics_ids": [
null
],
"filters": null,
"archived": false,
"deleted": true,
"created_by": {
"id": 0,
"uuid": "095be615-a8ad-4c33-8e9c-c7612fbf6c9f",
"distinct_id": "string",
"first_name": "string",
"last_name": "string",
"email": "user@example.com",
"is_email_verified": true,
"hedgehog_config": {},
"role_at_organization": "engineering"
},
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "web",
"exposure_criteria": {
"exposure_config": null,
"filterTestAccounts": null,
"multiple_variant_handling": null
},
"metrics": [
{
"completion_event": null,
"conversion_window": null,
"denominator": null,
"denominator_outlier_handling": null,
"goal": null,
"ignore_zeros": null,
"kind": "ExperimentMetric",
"lower_bound_percentile": null,
"metric_type": "funnel",
"name": null,
"numerator": null,
"numerator_outlier_handling": null,
"retention_window_end": null,
"retention_window_start": null,
"retention_window_unit": null,
"series": null,
"source": null,
"start_event": null,
"start_handling": null,
"threshold": null,
"upper_bound_percentile": null,
"uuid": null
}
],
"metrics_secondary": [
{
"completion_event": null,
"conversion_window": null,
"denominator": null,
"denominator_outlier_handling": null,
"goal": null,
"ignore_zeros": null,
"kind": "ExperimentMetric",
"lower_bound_percentile": null,
"metric_type": "funnel",
"name": null,
"numerator": null,
"numerator_outlier_handling": null,
"retention_window_end": null,
"retention_window_start": null,
"retention_window_unit": null,
"series": null,
"source": null,
"start_event": null,
"start_handling": null,
"threshold": null,
"upper_bound_percentile": null,
"uuid": null
}
],
"stats_config": null,
"scheduling_config": null,
"allow_unknown_events": false,
"_create_in_folder": "string",
"conclusion": "won",
"conclusion_comment": "string",
"primary_metrics_ordered_uuids": null,
"secondary_metrics_ordered_uuids": null,
"only_count_matured_users": true,
"update_feature_flag_params": false,
"status": "draft",
"is_legacy": true,
"user_access_level": "string"
}

Retrieve experiments eligible feature flags

Returns a paginated list of feature flags eligible for use in experiments.

Eligible flags must:

  • Be multivariate with at least 2 variants
  • Have "control" as the first variant key

Query parameters:

  • search: Filter by flag key or name (case insensitive)
  • limit: Number of results per page (default: 20)
  • offset: Pagination offset (default: 0)
  • active: Filter by active status ("true" or "false")
  • created_by_id: Filter by creator user ID
  • order: Sort order field
  • evaluation_runtime: Filter by evaluation runtime
  • has_evaluation_contexts: Filter by presence of evaluation contexts ("true" or "false")

Required API key scopes

feature_flag:read

Example request

GET /api/projects/:project_id/experiments/eligible_feature_flags
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/experiments/eligible_feature_flags/

Example response

Status 200 No response body

Retrieve experiments prompt templates

List the LLM metric templates that can be passed to create_from_prompt.

Required API key scopes

experiment:read

Example request

GET /api/projects/:project_id/experiments/prompt_templates
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/experiments/prompt_templates/

Example response

Status 200

Retrieve experiments requires flag implementation

Mixin for ViewSets to handle ApprovalRequired exceptions from decorated serializers.

This mixin intercepts ApprovalRequired exceptions raised by the @approval_gate decorator on serializer methods and converts them into proper HTTP 409 Conflict responses with change request details.

Required API key scopes

experiment:read

Example request

GET /api/projects/:project_id/experiments/requires_flag_implementation
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/experiments/requires_flag_implementation/

Example response

Status 200 No response body

Retrieve experiments stats

Mixin for ViewSets to handle ApprovalRequired exceptions from decorated serializers.

This mixin intercepts ApprovalRequired exceptions raised by the @approval_gate decorator on serializer methods and converts them into proper HTTP 409 Conflict responses with change request details.

Required API key scopes

experiment:read

Example request

GET /api/projects/:project_id/experiments/stats
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/experiments/stats/

Example response

Status 200 No response body

Community questions

Questions about this page? or post a community question.