Update an A/B experiment
Move an experiment through its lifecycle, or change its traffic split.
Move an experiment through its lifecycle, or change its traffic split.
Supported transitions::
draft -> active start splitting live traffic active -> paused stop splitting, keep the record active | paused -> concluded close the experiment
Three state rules, all answered with 409 (code 1201):
- Only one experiment per control agent may be ACTIVE. Conclude or pause the running one before activating another.
winneris only accepted once the experiment is concluded. Setting the winner on an active experiment is a 409 — but{"status": "concluded", "winner": "variant"}in a single request is legal and is the normal way to close an experiment.- An ACTIVE experiment cannot be deleted (see
DELETE).
Promoting the variant: set variant_traffic_pct to 100. Every call
against the control agent then routes to the variant, and nothing else has to
change — campaigns, batches and scheduled calls keep naming the control
agent, so there is no re-targeting step and no window in which some calls use
the old agent. Conversely 0 parks the variant without ending the
experiment.
Nothing can be cleared. A field sent as null is rejected with 400
rather than silently ignored; in particular a winner cannot be un-set once
recorded.
Rate limit: 2000 requests per minute per organization, counted together with every endpoint that has no stricter limit of its own. Exceeding it returns 429 with Retry-After; the X-RateLimit-* response headers report your remaining allowance on every call.
v2/agents/{agent_id}/versions/{version_id}Authorization
AuthorizationRequiredBearer <token>
Your Graine API key. Create one in the dashboard under Developers, or via POST /v2/api-keys. Send it as Authorization: Bearer <key>.
In: header
Request Body
application/jsonRequiredversion_nameVersion Name | null
New experiment name.
100descriptionDescription | null
New notes.
500variable_testedVariable Tested | null
New label for what is being tested.
200variant_traffic_pctVariant Traffic Pct | null
New traffic split. 0 sends every call to the control agent; 100 sends every call to the variant, which is how a variant is promoted.
0Maximum: 100statusStatus | null
draft | active | paused | concluded
winnerWinner | null
control | variant. Only accepted when the experiment is, or is becoming in this same request, concluded.
start_dateStart Date | null
ISO-8601 timestamp with a timezone offset. Informational.
end_dateEnd Date | null
ISO-8601 timestamp with a timezone offset. Informational.
Path Parameters
agent_idRequiredAgent Id
The CONTROL agent.
version_idRequiredVersion Id
Experiment identifier.
Query Parameters
organization_idOrganization Id
Must match the organisation the API key belongs to.
Response Body
200
The updated experiment.
version_idRequiredVersion Id
Experiment identifier.
main_agent_idRequiredMain Agent Id
The CONTROL agent. Always equal to the agent_id in the path.
variant_agent_idRequiredVariant Agent Id
The CHALLENGER agent that receives the split traffic.
version_nameRequiredVersion Name
Experiment name.
descriptionDescription | null
Free-text notes about the experiment.
variable_testedVariable Tested | null
What is being tested, e.g. 'voice', 'script', 'cadence'.
variant_traffic_pctRequiredVariant Traffic Pct
Percentage of calls routed to the variant (0-100). The remainder goes to the control agent. 0 pauses the variant in place; 100 promotes it.
statusRequiredStatus
draft | active | paused | concluded
winnerWinner | null
control | variant. Only ever set on a concluded experiment.
start_dateStart Date | null
ISO-8601 UTC. Informational; it does not gate routing.
end_dateEnd Date | null
ISO-8601 UTC. Informational; it does not gate routing.
created_byCreated By | null
Identifier of whoever created the experiment.
created_atCreated At | null
ISO-8601 UTC.
updated_atUpdated At | null
ISO-8601 UTC.
400
1000 — malformed or contradictory input: an unknown status token, an empty patch body, an explicit null, or a variant agent that does not exist in this organisation.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
401
1100 — missing, unknown or inactive API key. 1101 — a browser session token was presented.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
403
1102 — the key is valid but lacks the scope this endpoint requires, or names another organisation. GET /v2/scopes reports which scopes the key holds.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
404
1200 — no such agent, or no such version for that agent, in this organisation. Cross-tenant reads answer 404, never 403, so ids cannot be probed.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
409
1201 — the experiment's state does not allow this action: a second ACTIVE version for the same control agent, a DELETE against an ACTIVE version, or a winner set before the experiment is concluded.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
422
1001 — the body or query failed validation; the message names the first offending field.
errorRequiredinteger
Stable integer code from the error table. Branch on this, not on the message.
messageRequiredstring
One human-readable sentence. Wording may change; the code will not.
429
1300 — per-organisation rate limit exceeded. Carries Retry-After.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
503
1501 — a service this endpoint depends on is unreachable or returned a 5xx.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
504
1502 — a service this endpoint depends on did not respond in time.
errorRequiredError
Stable integer code from the /v2 error table. Branch on this.
messageRequiredMessage
One human-readable sentence. Wording may change; the code will not.
The updated experiment.

