Skip to main content
GrowthBook tells you that a variation moved a metric: a feature flag rolled out, an experiment reached significance, a variation lost on conversion. It can’t show you what a user in that variation actually experienced. Subtext can. GrowthBook is warehouse-native, so it routes every experiment exposure through your trackingCallback — attach the Subtext session URL there and each exposure carries a link back to the real session. Your agent reads the subtext_url, opens that person’s session, and walks the variation experience with screenshots, the component tree, network, and console. GrowthBook detects; Subtext diagnoses.
This guide assumes the Subtext capture snippet is installed and capturing sessions, and that the GrowthBook SDK (@growthbook/growthbook) is initialized with a trackingCallback.

Attach the session URL

GrowthBook doesn’t store user data itself — attributes are evaluated locally, and only your trackingCallback persists exposures. So attach the URL in two places: on the attributes (so it’s available to evaluate against) and through the tracking callback (so it lands in your exposure stream).

On the GrowthBook attributes

Attach the URL to the GrowthBook attributes with setAttributes. Spread the existing attributes first so you don’t wipe targeting fields. In React, put it in the same useEffect as FS('setIdentity').

Through the tracking callback

GrowthBook routes experiment exposures through trackingCallback. Read the attribute there so the URL lands in your warehouse exposure table alongside the experiment and variation.
Don’t read FS('getSession') at module top level — it returns null until the session has started. Don’t pass a bare object to setAttributes — it replaces all attributes, so spread gb.getAttributes() first. And don’t expect the URL to appear anywhere without a trackingCallback — GrowthBook evaluates locally and only your callback persists exposures. The URL changes on a new session and when FS('setIdentity') is called with a different uid, so re-call setAttributes whenever you re-identify the user; attributes are frozen until the next call.

From signal to session

However you first hear that a variation moved — a significance alert, a results review, a health warning — the path is the same: get to the subtext_url for a few exposed users, then hand them to your agent for a Detect-vs-Diagnose read. The result says the variation regressed; the session shows whether it rendered correctly, errored, or simply behaved in a way users disliked.
GrowthBook posts to Slack: “Experiment pricing-table-v2 reached significance — variation B is down on signup_rate.”Pull the regressed users’ exposures from where your tracking callback writes them:
Copy a few subtext_url values, then hand them to your agent:
In the experiment review, a variation’s lift is negative and the room wants to know whether it’s the design or a bug.From the experiment_viewed event in your analytics tool (PostHog / Amplitude / Mixpanel), open the Properties tab and copy subtext_url for a few users in the losing variation.
GrowthBook flags a sample-ratio mismatch or a suspicious metric anomaly, hinting the variation is broken for some users.Pull a sample of affected-variation exposures from the warehouse and copy subtext_url.
A “variation is broken” verdict invalidates the result — re-run after fixing — while a “design underperformed” verdict is a real finding. For a regression across several users, ask your agent to assemble one proof document (doc-create) with a screenshot per exposed user, then paste that single link into the GrowthBook experiment notes so the lift number carries its cause.

For agents

An autonomous agent can run the whole loop against GrowthBook directly: discover the regressed variation, extract the subtext_url, and hand each session to the Subtext MCP. GrowthBook ships an official MCP server — @growthbook/mcp, open source at github.com/growthbook/growthbook-mcp — but it runs locally over stdio (npx -y @growthbook/mcp@latest); there is no hosted or remote endpoint. Authenticate with env vars (GB_API_KEY is an API key or PAT; GB_EMAIL is required for flag and experiment tools). Docs live at docs.growthbook.io/integrations/mcp.
1

Discover the regressed variation

Call get_experiments with response mode full (metadata + results) or summary (results + metrics) to surface the regressed variation and metric directly. Without the MCP, hit the REST API — base https://api.growthbook.io/api (Cloud) or https://{domain}/api (self-host), auth Authorization: Bearer <API_KEY>:
Confirm field names against the OpenAPI spec at https://api.growthbook.io/api/v1/openapi.yaml.
2

Extract the session URL

The REST API and get_experiments return aggregated results only — no raw per-user exposure rows. GrowthBook is warehouse-native, so subtext_url lives on the experiment_viewed exposure table the trackingCallback writes:
With your own warehouse, the shape of experiment_viewed is whatever your trackingCallback pipeline writes — no GrowthBook setting changes it, so emit subtext_url as its own event property (as above) rather than nesting it. (If you instead use GrowthBook Cloud’s Managed Warehouse — where events are ingested via GrowthBook’s SDK tracking plugin, not your own analytics.track — you can register subtext_url as a Key Attribute on the data-source settings page to lift it into a top-level column; this applies to new events only.) Note that the MCP’s get_attributes returns the attribute schema, not a user’s stored values — it is not the path to a per-user subtext_url.
3

Hand off to Subtext

For each URL, call review-open(session_url=<subtext_url>) on the Subtext MCP, then step through the key moment in the variation for a Detect-vs-Diagnose read: the variation regressed versus did it actually break, or just underperform.
subtext_url only round-trips if the trackingCallback wrote it into the exposure stream at capture time (see Attach the session URL). No REST endpoint exposes raw exposures or per-user attribute values — per-user reads are warehouse-only. If you forward exposures to an event tracker (Segment / Amplitude / Mixpanel), you can read subtext_url off the experiment_viewed event there instead.