Skip to content
Select themeSelect language

`POST /api/intelligence/agent-experiments/{id}/variants` — add one variant to an existing experiment (#838 E3). Admin-only. Same validations as create; a variant added to a running experiment starts at zero runs, which is fair because every KPI is measured per variant. The variant name must be unique within the experiment (case-insensitively) — it is the review key, so a duplicate would make the scorecard ambiguous; a collision is a `409`.

POST
/api/intelligence/agent-experiments/{id}/variants
curl --request POST \
--url https://example.com/api/intelligence/agent-experiments/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/variants \
--header 'Content-Type: application/json' \
--data '{ "budget_policy": "example", "config": "example", "endpoint": "example", "harness": "example", "is_control": true, "model": "example", "name": "example", "prompt_policy": "example", "provider": "example", "runner": "example", "tool_profile": "example" }'
id
required
string format: uuid
Media typeapplication/json
object
budget_policy
config
endpoint
string | null
harness
string | null
is_control
boolean | null
model
required
string
name
required
string
prompt_policy
provider
required
string
runner
required
string
tool_profile
string | null
Examplegenerated
{
"budget_policy": "example",
"config": "example",
"endpoint": "example",
"harness": "example",
"is_control": true,
"model": "example",
"name": "example",
"prompt_policy": "example",
"provider": "example",
"runner": "example",
"tool_profile": "example"
}
Media typeapplication/json
object
budget_policy
required
config
required
created_at
required
string format: date-time
endpoint
string | null
experiment_id
required
string format: uuid
harness
required
string
id
required
string format: uuid
is_control
required
boolean
model
required
string
name
required
string
prompt_policy
required
provider
required
string
runner
required
string
tool_profile
required
string
workspace_id
required
string format: uuid
Examplegenerated
{
"budget_policy": "example",
"config": "example",
"created_at": "2026-04-15T12:00:00Z",
"endpoint": "example",
"experiment_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"harness": "example",
"id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0",
"is_control": true,
"model": "example",
"name": "example",
"prompt_policy": "example",
"provider": "example",
"runner": "example",
"tool_profile": "example",
"workspace_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}

Invalid variant

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden license_required license_expired bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited too_many_requests quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Permission denied

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden license_required license_expired bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited too_many_requests quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

Experiment not found

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden license_required license_expired bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited too_many_requests quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}

A variant with that name already exists in this experiment

Media typeapplication/json

The canonical JSON body of every error response — the single source of truth the frontend binds to. Every AppError serializes as this exact shape, and the generated OpenAPI component ApiErrorBody (with its ErrorCode enum) is what the frontend error schema is generated from, so there is no hand-written error schema on either end.

object
code
required

Machine-readable, stable error code.

string
Allowed values: not_found unauthorized forbidden license_required license_expired bad_request unprocessable precondition_failed conflict method_not_allowed rate_limited too_many_requests quota_exceeded database_error docker_error vault_error internal_error
details
One of:
null
error
required

Human-readable message (the server’s English text; the client may localize by code).

string
Example
{
"code": "not_found"
}