# Experiment Stop

> Stop a running GrowthBook experiment via the REST API, optionally declaring a winning variation and rolling it out to 100% of eligible traffic. Use when the user says "stop this experiment", "end the A/B test", "declare a winner for X", "ship the winning variation", "roll back the test", or "we're done with this experiment". For interpreting results before deciding, use experiment-analyze first.

- **Type:** Skill
- **Install:** `agentstack add skill-growthbook-skills-experiment-stop`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [growthbook](https://agentstack.voostack.com/s/growthbook)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [growthbook](https://github.com/growthbook)
- **Source:** https://github.com/growthbook/skills/tree/main/skills/experiment-stop

## Install

```sh
agentstack add skill-growthbook-skills-experiment-stop
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# experiment-stop

Stop a running experiment, optionally declaring a winning variation and ramping it to all eligible traffic via a temporary rollout. The endpoint is `POST /api/v1/experiments//stop` (a dedicated endpoint, not the generic update). All variation references are **variation ID strings** like `var_abc123`, not 0-based integer indexes.

All API calls go through the bundled helper: `${CLAUDE_PLUGIN_ROOT}/scripts/gb-call`. It needs `GB_API_KEY` — set in your shell, or written to `~/.config/growthbook/.env` by `/growthbook:setup`. If unset or invalid, gb-call's error message points back at `/growthbook:setup`.

## Workflow

1. **Fetch the current experiment.**

   ```bash
   gb-call GET /api/v1/experiments/
   ```

   Check the `status` field. Only `running` experiments should be stopped via this skill. If `status === "draft"`, the experiment hasn't started — the user wants to delete it, not stop it (different operation). If `status === "stopped"`, it's already done.

   Also capture the `type` field. If `type === "multi-armed-bandit"`, halt and tell the user this skill targets standard A/B tests; bandits have their own lifecycle (stop is similar but interpretation and rollout differ — recommend they review in the UI before scripting).

2. **Show the user the variations table.** Surface the variations as the API records them — capture each one's `variationId` (the string ID, e.g. `var_treatment_a`) and `name`. The user picks **by the variation ID string**, not by index:

   ```
   The experiment has these variations:
     var_control      0: Control       —   (lift: baseline, users: N)
     var_treatment_a  1: Treatment A   —   (lift: +2.3%, users: N)
     var_treatment_b  2: Treatment B   —   (lift: -0.8%, users: N)

   Which variation should ship? Reply with the variation ID (e.g. var_treatment_a),
   or say "no winner" to stop without declaring.
   ```

   If the user has not already run `experiment-analyze`, suggest doing that first so the decision is informed.

3. **Decide on temporary rollout.** If the user has a winner and wants to ship now, offer the temporary-rollout path:

   > "Want me to also enable a temporary rollout? That keeps this experiment in the SDK payload and forces 100% of eligible traffic to ``. It's the cleanest 'ship the winner' option — the linked feature flag's rule stays in place but routes everyone to the winner. You can toggle it off later with `modify-temporary-rollout` or clean up the rule via `flag-targeting`."

   If yes, set `enableTemporaryRollout: true` and `releasedVariationId: ` in the payload. If no, the experiment stops but you leave the flag alone — surface that the user will need to clean up the `experiment-ref` rule manually.

4. **Confirm intent.** Restate the action in plain English:

   > "Stopping experiment '', declaring variation `var_treatment_a` (Treatment A) as the winner, and enabling temporary rollout to ship it to 100% of eligible traffic."

   Get explicit confirmation before posting. Stopping itself is reversible (you can restart), but declaring a winner and enabling a rollout produces downstream signals — don't do it on a hunch.

5. **Build the payload.** The body is **flat**; there is no nested `resultSummary`.

   Stop without a declared winner:

   ```json
   { "results": "inconclusive" }
   ```

   Stop with a declared winner, no rollout:

   ```json
   {
     "results": "won",
     "winnerVariationId": "",
     "analysis": ""
   }
   ```

   Stop with a declared winner and ship via temporary rollout:

   ```json
   {
     "results": "won",
     "winnerVariationId": "",
     "releasedVariationId": "",
     "enableTemporaryRollout": true,
     "analysis": ""
   }
   ```

   Field reference:

   - `results` — required. One of `"won"`, `"lost"`, `"inconclusive"`, `"dnf"` (did not finish).
   - `winnerVariationId` — string variation ID (e.g. `var_abc123`). Required when `results === "won"` and the experiment has multiple test variations.
   - `releasedVariationId` — string variation ID. Required when `enableTemporaryRollout: true`. Usually equals `winnerVariationId`.
   - `enableTemporaryRollout` — boolean. Keeps the stopped experiment in the SDK payload and forces traffic to the `releasedVariationId`.
   - `analysis` — markdown summary shown on the experiment results page.
   - `reason` — optional reason text stored on the latest phase metadata.
   - `dateEnded` — optional ISO datetime; defaults to now.

6. **Post the update.**

   ```bash
   echo '' | gb-call POST /api/v1/experiments//stop -
   ```

7. **State what happens next, and link to the experiment.** Tell the user:
   - The experiment is now stopped; no more traffic accumulates against the experiment.
   - If a winner was declared, the variation ID that "won."
   - **Direct UI link** so they can verify the stopped state, the recorded `analysis`, and the rollout status:
     ```
     /experiment/
     ```
     Derive `` from `GB_API_URL` by swapping `api.` → `app.` (matches `experiment-launch`'s convention; on the default cloud host this produces `https://app.growthbook.io`).
   **What happens to the flag?** Surface the disposition clearly based on what was sent:

   **With temporary rollout (`enableTemporaryRollout: true`):** the winner is live — traffic is already routed to it via the existing experiment-ref rule. No further action required until the team decides to clean up the flag (which can happen days or weeks later). When ready:
   - **Convert to permanent rule:** remove the experiment-ref rule via `flag-rules`, add a permanent force rule for the winner via `flag-targeting`.
   - **Clean up entirely:** if the feature will be inlined in code, use `flag-cleanup` to walk through code cleanup and archive/delete the flag.
   - **Roll back:** turn off the temporary rollout first (`echo '{"enableTemporaryRollout": false}' | gb-call POST /api/v1/experiments//modify-temporary-rollout -`), then remove the experiment-ref rule via `flag-rules`.

   **Without temporary rollout:** the experiment-ref rule is still on the flag, routing traffic to a stopped experiment (users will get the control value). The flag needs attention:
   - **Option A — Ship the winner:** set `defaultValue` to the winner's value via `flag-default-value`, then remove the experiment-ref rule via `flag-rules`. Or use `flag-targeting` to add a permanent force rule serving the winner, then remove the experiment-ref rule.
   - **Option B — Roll back:** the flag's default value already serves the control — just remove the experiment-ref rule via `flag-rules` and the flag returns to its pre-experiment state.
   - **Option C — Full cleanup:** use `flag-cleanup` to inline the value in code and archive/delete the flag.

## Guardrails

- **`winnerVariationId` is a variation ID _string_ (e.g. `var_abc123`), not an integer index, not a name, not the variation's `key`.** Get this wrong and the request 400s or the wrong variation is recorded as the winner.
- **The endpoint is `POST /api/v1/experiments//stop`, not `POST /api/v1/experiments/`.** The body shape is flat — there is no `resultSummary` wrapper. The generic update endpoint exists but takes different fields; use the dedicated stop endpoint here.
- **Never declare a winner the user didn't pick.** Even if the results look obvious, force the user to choose the variation ID. Surface results, but don't pre-fill. _Skill convention, not GrowthBook policy: the API accepts any variation ID as `winnerVariationId`; the safety is enforced here, not server-side._
- **Don't stop drafts.** A `draft` experiment isn't running — what the user wants there is `DELETE /api/v1/experiments/` (separate skill, not covered here). Surface the confusion if they ask to stop a draft.
- **Don't stop already-stopped experiments.** The API may accept the call but it's effectively a no-op; tell the user it's already done. To change the results metadata on an already-stopped experiment, post again with the new `results` / `winnerVariationId` / `analysis`.
- **Bandits are out of scope.** `type === "multi-armed-bandit"` experiments need different handling — halt and tell the user.
- **`releasedVariationId` is required when `enableTemporaryRollout: true`.** The API rejects the combination otherwise. They're usually the same as `winnerVariationId` but don't have to be — e.g., a "lost" result that rolls everyone back to control would set `releasedVariationId: ` with `results: "lost"`.
- **Always remind about the linked flag.** Stopping the experiment does not remove the `experiment-ref` rule from the linked flag. Without a temporary rollout, the flag keeps routing to a stale experiment until the user cleans the rule up.
- **`analysis` should explain the decision in plain English (markdown).** Future readers (including future-self) will want context. Don't leave it blank when declaring a winner.
- **Run `experiment-analyze` first if the user hasn't.** Stopping based on a glance at the dashboard is a common mistake — interim numbers can flip, and the data-quality checks in `experiment-analyze` can flag results that look conclusive but aren't.

## Endpoints used

- `GET /api/v1/experiments/` — fetch state, variations, and `type`
- `POST /api/v1/experiments//stop` — stop and optionally declare a winner + temporary rollout
- `POST /api/v1/experiments//modify-temporary-rollout` — toggle the temporary rollout off (or on) after stopping, without re-running this skill

## Handoffs

- `experiment-analyze` — run first if the user wants to interpret results before deciding.
- `flag-rules` — remove the experiment-ref rule after stopping (always needed eventually).
- `flag-targeting` — add a permanent force rule serving the winner value (replaces the experiment-ref rule).
- `flag-default-value` — set the flag's default to the winner value when shipping without a targeting rule.
- `flag-cleanup` — if the feature is fully shipped and the flag should be removed from code and archived.
- `experiment-design` and `experiment-launch` — for the next test if this one informed a follow-up.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [growthbook](https://github.com/growthbook)
- **Source:** [growthbook/skills](https://github.com/growthbook/skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-growthbook-skills-experiment-stop
- Seller: https://agentstack.voostack.com/s/growthbook
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
