# Experiments

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/http-api/experiments/
> Summary: The experiments endpoints of the Tracon HTTP API — 9 operations.

9 operations. `{prefix}` is the route prefix passed to
`MapTracon`; the template uses `/tracon`.

## GET {prefix}/api/experiments

**Operation ID:** `TraconListExperiments`

**Lists a tenant's A/B experiments.**

Experiments in every state are returned — Draft, Running, and Stopped — because a stopped experiment is still the record its results are read from. At most one of them per agent can be Running. The entries carry the variant weights, so a client can show the traffic split without a second call.

**Authorization:** bearer authentication; `Reader` role policy when that policy is registered; `ExperimentsRead` API-key scope.

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → array of [`Experiment`](/http-api/schemas/experiment/) | — |

## GET {prefix}/api/experiments/{name}

**Operation ID:** `TraconGetExperiment`

**Gets a single A/B experiment.**

The response is the experiment's definition — arms, weights, status — not its outcome; read the per-arm counts from the results endpoint and the canary rule from the canary endpoint. Experiments are scoped to the calling tenant, and a name that belongs to another tenant is reported as 404.

**Authorization:** bearer authentication; `Reader` role policy when that policy is registered; `ExperimentsRead` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `name` | path | yes | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`Experiment`](/http-api/schemas/experiment/) | — |

## PUT {prefix}/api/experiments/{name}

**Operation ID:** `TraconSaveExperiment`

**Creates or updates an experiment.**

An experiment can only be set up between versions of the same agent; code-sourced agents have no version history, so they are rejected. Variant weights must sum to 100.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `ExperimentsAdmin` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `name` | path | yes | `string` | — |

**Request body** (required):

- `application/json` → [`ExperimentSaveRequest`](/http-api/schemas/experimentsaverequest/)

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`Experiment`](/http-api/schemas/experiment/) | — |

## DELETE {prefix}/api/experiments/{name}

**Operation ID:** `TraconDeleteExperiment`

**Deletes an experiment. A running experiment must be stopped first.**

Deleting a Running experiment returns 409; stop it first, so traffic is never left splitting against a definition that no longer exists. Runs already assigned to an arm keep their assignment and stay readable, but the per-arm results endpoint disappears with the experiment — export the results before deleting. An unknown name returns 404.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `ExperimentsAdmin` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `name` | path | yes | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **204** No Content | — | — |

## GET {prefix}/api/experiments/{name}/canary

**Operation ID:** `TraconGetExperimentCanary`

**Gets the canary rule and its current evaluation.**

The evaluation is not persisted; it is recalculated on every call using current run results.

**Authorization:** bearer authentication; `Reader` role policy when that policy is registered; `ExperimentsRead` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `name` | path | yes | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`ExperimentCanaryResponse`](/http-api/schemas/experimentcanaryresponse/) | — |

## PUT {prefix}/api/experiments/{name}/canary

**Operation ID:** `TraconSetExperimentCanary`

**Defines or removes the canary rule (a 'null' body removes it).**

Can only be defined on two-arm experiments: canaryVariant is the canary, and the single remaining arm counts as control. Works regardless of the experiment's status (Draft or Running).

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `ExperimentsAdmin` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `name` | path | yes | `string` | — |

**Request body** (optional):

- `application/json` → [`CanaryPolicy`](/http-api/schemas/canarypolicy/)

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`Experiment`](/http-api/schemas/experiment/) | — |

## GET {prefix}/api/experiments/{name}/results

**Operation ID:** `TraconGetExperimentResults`

**Gets a per-arm summary of count, error rate, tokens, and duration.**

There is no statistical claim of a 'winner'; raw counts are shown.

**Authorization:** bearer authentication; `Reader` role policy when that policy is registered; `ExperimentsRead` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `name` | path | yes | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`ExperimentResultsResponse`](/http-api/schemas/experimentresultsresponse/) | — |

## POST {prefix}/api/experiments/{name}/start

**Operation ID:** `TraconStartExperiment`

**Starts the experiment; traffic begins splitting according to the weights.**

Only one experiment can run for the same agent at a time.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `ExperimentsAdmin` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `name` | path | yes | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`Experiment`](/http-api/schemas/experiment/) | — |

## POST {prefix}/api/experiments/{name}/stop

**Operation ID:** `TraconStopExperiment`

**Stops the experiment; new runs go to the current version.**

Stopping affects only new runs: a run already in flight keeps the arm it was assigned, and the recorded results stay intact and readable afterwards. Stopping an experiment that is not Running returns 409, and so does an unknown name — this endpoint does not distinguish the two. Once stopped, the agent's own current version serves all traffic again, and the same agent becomes free for another experiment.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `ExperimentsAdmin` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `name` | path | yes | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`Experiment`](/http-api/schemas/experiment/) | — |
