# Create decide

URL: https://docs.hanzo.ai/docs/openapi/experiment/post-experiment-by-id-decide

> Promotes one variant to the whole rollout and records who decided.

`POST /v1/experiment/{id}/decide`

> [Experiment →](https://docs.hanzo.ai/docs/openapi/experiment) · [All API references →](https://docs.hanzo.ai/docs/openapi) · [Get started →](https://docs.hanzo.ai/docs/guides)

|               |                                                  |
| ------------- | ------------------------------------------------ |
| **Address**   | `https://api.hanzo.ai/v1/experiment/{id}/decide` |
| **Method**    | `POST`                                           |
| **Operation** | `post_experiment_by_id_decide`                   |
| **Auth**      | `Authorization: Bearer $HANZO_API_KEY`           |

Promotes one variant to the whole rollout and records who decided.

It rewrites the assignment flag so the named winner serves 100% of the rollout
and every other arm 0%, preserving the flag's targeting groups and payloads,
then stamps the experiment decided with the winner, the deciding credential and
the time. This is a production behaviour change that takes effect immediately
for every subject the flag evaluates.

It requires an ORG ADMIN of the caller's own org — a stricter gate than the rest
of this surface, matching the flags write plane, because promoting is a flag
write. The admin check runs AFTER the experiment is found, so a caller from
another tenant is answered not-found rather than forbidden and learns nothing
about what exists.

An experiment whose assignment flag has gone missing is a conflict rather than a
silent no-op — there is nothing to promote.

Deciding is NOT terminal. A second call re-promotes a different variant and
re-stamps the row; the status stays decided and the previous winner is
overwritten with no record that it was ever chosen. Nothing here reverts the
flag to its original weights either, so an experiment cannot be un-decided
through this route — restoring a split means writing the flag definition back
through the flags plane.

## Request

2 fields, body `application/json` (required).

| Field    | In   | Type   | Required | Description                       |
| -------- | ---- | ------ | -------- | --------------------------------- |
| `id`     | path | string | yes      |                                   |
| `winner` | body | string | yes      | Winner is the variant to promote. |

## Response

| Status    | Body             | Meaning |
| --------- | ---------------- | ------- |
| `200`     | experiment.Trial | ok      |
| `default` | problem-details  | refused |

`200` body — 18 fields.

| Field                | In   | Type              | Always | Description                                                              |
| -------------------- | ---- | ----------------- | ------ | ------------------------------------------------------------------------ |
| `createdAt`          | body | string            | —      | when it started assigning                                                |
| `createdBy`          | body | string            | —      | the credential that registered it                                        |
| `decidedAt`          | body | string            | —      | when the promotion took effect                                           |
| `decidedBy`          | body | string            | —      | the credential that promoted the winner                                  |
| `exposureEvent`      | body | string            | —      | the event that enrols a subject — the analysis denominator               |
| `flagKey`            | body | string            | —      | the assignment flag this experiment drives                               |
| `id`                 | body | string            | —      | the experiment's slug, unique within the project                         |
| `metricEvent`        | body | string            | —      | the event that counts as a conversion — the numerator                    |
| `name`               | body | string            | —      | free text for a reader                                                   |
| `project`            | body | string            | —      | the sub-scope within the org, stamped from the principal                 |
| `status`             | body | string            | —      | running while it assigns and measures, decided once a winner is promoted |
| `subjectKind`        | body | string            | —      | the unit assigned and measured: user, org, session or audience           |
| `variants`           | body | experiment.Arm\[] | —      | the arms, weighted, one of them the control                              |
| `variants[].control` | body | boolean           | —      | true on the baseline arm every other arm is compared to                  |
| `variants[].key`     | body | string            | —      | the arm's slug, unique within the experiment                             |
| `variants[].payload` | body | any               | —      | opaque JSON the arm carries, which the consumer interprets               |
| `variants[].weight`  | body | number (double)   | —      | its share of the rollout; the arms sum to 100                            |
| `winner`             | body | string            | —      | the arm promoted to the whole rollout                                    |

Failure carries the platform error shape — see [Errors](https://docs.hanzo.ai/docs/errors).

## Examples

**CLI**

```bash
hanzo experiment decide <id> --winner <winner>
```

**SDK**

**.ts**

```ts
import { Configuration, ExperimentApi } from 'hanzoai';

const api = new ExperimentApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postExperimentByIdDecide({ id: 'id', winner: "<winner>" });
```

**.py**

```python
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_by_id_decide(id='id', winner="<winner>")
```

**.go**

```go
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.ExperimentAPI.PostExperimentByIdDecide(context.Background()).Execute()
if err != nil {
	return err
}
```

**.rs**

```rust
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_by_id_decide(&cfg, Default::default()).await?;
```

**.java**

```java
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).postExperimentByIdDecide();
```

**HTTP**

```bash
curl -X POST https://api.hanzo.ai/v1/experiment/<id>/decide \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "winner": "<winner>"
     }'
```

**MCP**

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:

```bash
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](https://docs.hanzo.ai/docs/openapi/experiment) · [All Hanzo APIs](https://docs.hanzo.ai/docs/openapi) · [Interactive reference](https://docs.hanzo.ai/docs/openapi/reference)
