Create experiment

Registers a controlled experiment AND puts its assignment flag live, in that order, so the arms start bucketing subjects the moment this returns 201 — the flag is created active at 100% rollout, with each variant weighted as declared.

POST /v1/experiment

Addresshttps://api.hanzo.ai/v1/experiment
MethodPOST
Operationpost_experiment
AuthAuthorization: Bearer $HANZO_API_KEY

Registers a controlled experiment AND puts its assignment flag live, in that order, so the arms start bucketing subjects the moment this returns 201 — the flag is created active at 100% rollout, with each variant weighted as declared. There is no separate start call; creating IS starting.

A variant carries an opaque payload this primitive never interprets: a feature config, an ad-creative id, a subject line, a model id.

Requires a validated principal, and refuses without one. The org and project are taken from that principal and the creator is stamped from the credential — none of the three is a body field, so an experiment cannot be filed against another tenant. An id already used in this project is a conflict, never a silent overwrite: re-creating would stomp the assignment flag of a run in progress.

It fails closed on the flag write. An experiment whose assignment flag does not exist would assign nobody, so if that write fails nothing is registered.

Request

11 fields, body application/json (required).

FieldInTypeRequiredDescription
exposureEventbodystring—ExposureEvent is the event that marks a subject as enrolled — the analysis denominator — defaulting to the SDK's $feature_flag_called marker.
flagKeybodystring—FlagKey names the assignment flag this experiment writes, defaulting to exp_<id>.
idbodystringyesID is the experiment's slug, claimed once per project.
metricEventbodystringyesMetricEvent is the event that counts as a conversion — the analysis numerator.
namebodystring—Name is free text for a reader; the id is what addresses the experiment.
subjectKindbodystring—SubjectKind is the unit assigned and measured: user (the default), org, session or audience.
variantsbodyexperiment.Arm[]yesArms are the arms, at least two.
variants[].controlbodyboolean—true on the baseline arm every other arm is compared to
variants[].keybodystring—the arm's slug, unique within the experiment
variants[].payloadbodyany—opaque JSON the arm carries, which the consumer interprets
variants[].weightbodynumber (double)—its share of the rollout; the arms sum to 100

Response

StatusBodyMeaning
201experiment.Trialcreated
defaultproblem-detailsrefused

201 body — 18 fields.

FieldInTypeAlwaysDescription
createdAtbodystring—when it started assigning
createdBybodystring—the credential that registered it
decidedAtbodystring—when the promotion took effect
decidedBybodystring—the credential that promoted the winner
exposureEventbodystring—the event that enrols a subject — the analysis denominator
flagKeybodystring—the assignment flag this experiment drives
idbodystring—the experiment's slug, unique within the project
metricEventbodystring—the event that counts as a conversion — the numerator
namebodystring—free text for a reader
projectbodystring—the sub-scope within the org, stamped from the principal
statusbodystring—running while it assigns and measures, decided once a winner is promoted
subjectKindbodystring—the unit assigned and measured: user, org, session or audience
variantsbodyexperiment.Arm[]—the arms, weighted, one of them the control
variants[].controlbodyboolean—true on the baseline arm every other arm is compared to
variants[].keybodystring—the arm's slug, unique within the experiment
variants[].payloadbodyany—opaque JSON the arm carries, which the consumer interprets
variants[].weightbodynumber (double)—its share of the rollout; the arms sum to 100
winnerbodystring—the arm promoted to the whole rollout

Failure carries the platform error shape — see Errors.

Examples

hanzo experiment create \
  --id <id> \
  --metric-event <metricEvent> \
  --variants '[{"control":false,"key":"<key>","payload":"<payload>","weight":0}]'
import { Configuration, ExperimentApi } from 'hanzoai';

const api = new ExperimentApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postExperiment({ id: "<id>", metricEvent: "<metricEvent>", variants: [{"control":false,"key":"<key>","payload":"<payload>","weight":0}] });
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ExperimentApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ExperimentApi(client).post_experiment(id="<id>", metric_event="<metricEvent>", variants=[{"control":false,"key":"<key>","payload":"<payload>","weight":0}])
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.ExperimentAPI.PostExperiment(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::apis::{configuration::Configuration, experiment_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = experiment_api::post_experiment(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ExperimentApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new ExperimentApi(client).postExperiment();
curl -X POST https://api.hanzo.ai/v1/experiment \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "id": "<id>",
       "metricEvent": "<metricEvent>",
       "variants": [
         {
           "control": false,
           "key": "<key>",
           "payload": "<payload>",
           "weight": 0
         }
       ]
     }'

MCP reaches experiment through the experiment tool, which names its 7 operations with its own verbs — this one among them, under a name only MCP declares. describe explains any of them:

curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_experiments"
         }
       }
     }'

Experiment API · All Hanzo APIs · Interactive reference

Was this page useful?