Experiments
For instructions on how to authenticate to use this endpoint, see API overview.
Endpoints
POST | |
POST | |
POST | |
POST | |
POST | |
GET | |
POST | |
POST | |
POST | |
POST | |
GET | |
GET | |
POST | |
GET |
Create experiments recalculate timeseries
Mixin for ViewSets to handle approval-gate exceptions raised from decorated serializers.
Intercepts ApprovalRequired (409) and PolicyConflict (400) raised by the @approval_gate decorator on serializer methods and converts them into the same responses the viewset path produces (see decorators._result_to_response), so both paths share one contract.
Required API key scopes
experiment:writePath parameters
- idinteger
Request parameters
- namestring
- descriptionstringnull
- start_datestringnull
- end_datestringnull
- feature_flag_keystring
- holdout_idintegernull
- parameters
- running_time_calculation
- excluded_variantsarraynull
- secondary_metrics
- saved_metrics_idsarraynull
- filters
- archivedbooleanDefault:
false - deletedbooleannull
- type
- exposure_criteria
- metrics
- metrics_secondary
- stats_config
- scheduling_config
- allow_unknown_eventsbooleanDefault:
false - _create_in_folderstring
- conclusion
- conclusion_commentstringnull
- repositorystringnull
- primary_metrics_ordered_uuids
- secondary_metrics_ordered_uuids
- only_count_matured_usersboolean
- update_feature_flag_paramsbooleanDefault:
false - versionintegernull
- original_experimentobjectnull
Example request
POST /api /projects /:project_id /experiments /:id /recalculate_timeseriesExample response
Status 200 No response body
Create experiments reset
Reset an experiment back to draft state.
Clears start/end dates, conclusion, archived flag, and any flag-cleanup task pointer. The feature flag is left unchanged — users continue to see their assigned variants.
Previously collected events still exist but won't be included in results unless the start date is manually adjusted after re-launch.
Returns 400 if the experiment is already in draft state.
Required API key scopes
experiment:writePath parameters
- idinteger
Response
Example request
POST /api /projects /:project_id /experiments /:id /resetExample response
Status 200
Create experiments resume
Resume a paused experiment.
Reactivates the linked feature flag so it is returned by /decide again. Users are re-bucketed deterministically into the same variants they had before the pause, and exposure tracking resumes. Returns 400 if the experiment is not running or is not paused.
Required API key scopes
experiment:writePath parameters
- idinteger
Response
Example request
POST /api /projects /:project_id /experiments /:id /resumeExample response
Status 200
Create experiments session buckets
Session recordings of this experiment matching a bucket.
Answers the questions a recordings query can't express on its own — "fired any of these metrics", "fired none of them", "was exposed but never completed the funnel in this session" — by returning a bounded, most-recent-first list of session IDs to pass back as a recordings query's session_ids. POST because the metric list doesn't fit a query string; the endpoint only reads.
Session-scoped and goal-free: the set describes what happened in each session, while the experiment analysis counts per person over the whole run window. A session can be in the drop-off bucket while the same person converts in a later one.
Required API key scopes
experiment:readsession_recording:readPath parameters
- idinteger
Request parameters
- bucket
- metric_uuidsarray
- variantstringnull
- limitintegerDefault:
100
Response
Example request
POST /api /projects /:project_id /experiments /:id /session_bucketsExample response
Status 200
Create experiments ship variant
Ship a variant and (optionally) end the experiment.
Updates the feature flag so the selected variant gets 100% of the variant
distribution. By default, existing release conditions on the flag are preserved
untouched — the variant is served only to users who already match them. Pass
release_to_everyone: true to also prepend a catch-all release condition
that rolls the variant out to 100% of users (overrides any existing release
conditions on the flag).
Can be called on both running and stopped experiments. If the experiment is still running, it will also be ended (end_date set and status marked as stopped). If the experiment has already ended, only the flag is rewritten - this supports the "end first, ship later" workflow.
If an approval policy requires review before changes on the flag take effect, the API returns 409 with a change_request_id. The experiment is NOT ended until the change request is approved and the user retries.
Returns 400 if the experiment is in draft state, the variant_key is not found on the flag, or the experiment has no linked feature flag.
Required API key scopes
experiment:writePath parameters
- idinteger
Request parameters
- conclusion
- conclusion_commentstringnull
- open_cleanup_prbooleanDefault:
false - repositorystringnull
- set_repository_as_team_defaultbooleanDefault:
false - variant_keystring
- release_to_everyonebooleanDefault:
false
Response
Example request
POST /api /projects /:project_id /experiments /:id /ship_variantExample response
Status 200
Retrieve experiments timeseries results
Mixin for ViewSets to handle approval-gate exceptions raised from decorated serializers.
Intercepts ApprovalRequired (409) and PolicyConflict (400) raised by the @approval_gate decorator on serializer methods and converts them into the same responses the viewset path produces (see decorators._result_to_response), so both paths share one contract.
Required API key scopes
experiment:readPath parameters
- idinteger
Query parameters
- fingerprintstring
- metric_uuidstring
Example request
GET /api /projects /:project_id /experiments /:id /timeseries_resultsExample 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:writePath parameters
- idinteger
Response
Example request
POST /api /projects /:project_id /experiments /:id /unarchiveExample response
Status 200
Create experiments unfreeze exposure
Reopen enrollment on an exposure-frozen experiment.
Removes the snapshot-cohort condition and freeze markers from every release group, restoring the flag's original targeting: new users can enroll again and already-enrolled users keep their assigned variant. The snapshot cohort is soft-deleted. The serialized status returns to 'running'.
Returns 400 if the experiment is not running or its exposure is not frozen.
Required API key scopes
experiment:writePath parameters
- idinteger
Response
Example request
POST /api /projects /:project_id /experiments /:id /unfreeze_exposureExample response
Status 200
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:readRequest parameters
- metric_type
- minimum_detectable_effectnumber
- number_of_variantsintegerDefault:
2 - exposure_rate_per_daynumbernull
- baseline_valuenumbernull
- variancenumbernull
- baseline_stats
Response
Example request
POST /api /projects /:project_id /experiments /calculate_running_timeExample response
Status 200
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:readRequest parameters
- prompt_namestring
- versionsarray
- templatesarray
- namestring
- feature_flag_keystring
- descriptionstring
Response
Example request
POST /api /projects /:project_id /experiments /create_from_promptExample response
Status 200
Retrieve experiments prompt templates
List the LLM metric templates that can be passed to create_from_prompt.
Required API key scopes
experiment:readExample request
GET /api /projects /:project_id /experiments /prompt_templatesExample response
Status 200
Retrieve experiments session context
Resolve which experiments (and variants) a session recording saw. Variants come from the session's $feature_flag_called events and stamped $feature/<key> event properties — flag evaluation, which may differ from an experiment's exposure criteria.
Required API key scopes
experiment:readsession_recording:readQuery parameters
- session_idstring
Response
Example request
GET /api /projects /:project_id /experiments /session_contextExample response
Status 200
Create experiments session contexts
Resolve experiment context for a batch of session recordings.
Batch variant of session_context, used to prefetch the replay player's experiments
box for a whole recordings list in one request. POST because the id list doesn't fit a
query string; the endpoint only reads. Already-computed sessions are served from (and
cold ones written to) the same short-lived per-viewer cache the single-session endpoint
uses, so opening any prefetched recording renders its context instantly. Sessions whose
recording metadata doesn't exist yet are omitted from the response, as are recordings
the caller can't access and sessions beyond the batch's recording-day budget (each
distinct recording day costs its own set of ClickHouse scans, so only the most recent
days are computed per request).
Required API key scopes
experiment:readsession_recording:readRequest parameters
- session_idsarray
Response
Example request
POST /api /projects /:project_id /experiments /session_contextsExample response
Status 200
Retrieve experiments stats
Mixin for ViewSets to handle approval-gate exceptions raised from decorated serializers.
Intercepts ApprovalRequired (409) and PolicyConflict (400) raised by the @approval_gate decorator on serializer methods and converts them into the same responses the viewset path produces (see decorators._result_to_response), so both paths share one contract.
Required API key scopes
experiment:readExample request
GET /api /projects /:project_id /experiments /stats