# Garasu

Create a project, connect PostHog, and give an assistant the Garasu MCP.

Human pages start at https://garasu.co/docs. This file is the same guide in Markdown. Fetch one page with https://garasu.co/docs.md?page=start (or projects, posthog, how-it-works, mcp, tools, tools/<tool_name>).

Server card: https://garasu.co/.well-known/mcp.json

OpenAPI: https://garasu.co/openapi.json

# Get started

Create an account, add a project, and connect an assistant.

Garasu stores finished A/B tests and the product claims those tests support. You read that library in the app. An assistant reads the same library through the MCP before it proposes the next test.

1. [Create an account](https://garasu.co/sign-up).
2. Open the [app](https://garasu.co/app). Garasu puts you in an organisation.
3. Add a [project](/docs/projects) with a name and the site URL.
4. [Connect PostHog](/docs/posthog) when that project already has experiments there.
5. [Connect the MCP](/docs/mcp) so Codex, Claude, Grok, or another client can list projects and read learnings.

Free stores 50 imported experiments and 1 project. Pro stores 250. Max stores 1,000. Learnings are not capped.

Agents can read this guide as one file at [/docs.md](/docs.md). A short index lives at [/llms.txt](/llms.txt). The server card is [https://garasu.co/.well-known/mcp.json](https://garasu.co/.well-known/mcp.json). Typed tool schemas are at [https://garasu.co/openapi.json](https://garasu.co/openapi.json).

# Create your first project

A project is the library for one site. You create it in the app.

Projects are created in the app, not by the public MCP. `list_projects`, `get_project`, and `update_project` read or edit a project that already exists.

1. Open Overview.
2. Choose New project.
3. Fill in the form.
   - Name. Required. 1 to 80 characters.
   - URL. The site this project is about.
   - Description. Optional. Up to 500 characters.
4. Save. Garasu opens the project page.

That page is where you connect PostHog, read learnings, and open experiments. The sidebar lists every project in the organisation.

Free includes 1 project. Pro and Max do not cap the number of projects.

To rename a project later, edit it in the app, or call `update_project` with the project id. Pass an empty url to clear the URL. Omit any field you want to leave as it is.

# Connect PostHog

Import concluded PostHog experiments into a Garasu project.

PostHog is the experiment source Garasu imports on its own. GrowthBook, Statsig, and other platforms come in when an assistant calls `import_experiment`.

On the project page, open the PostHog card.

1. Pick the region. United States is `us.posthog.com`. European Union is `eu.posthog.com`. Use the host where that PostHog project lives.
2. Choose Connect PostHog.
3. Sign in to PostHog and allow Garasu. The scope is read access to experiments.
4. Garasu imports concluded experiments, up to your plan cap, and starts writing learnings.

Tests that are still running stay in PostHog until they end. A later sync picks up experiments that concluded after the last import.

Disconnect from the same card. That stops future imports. It does not delete experiments already stored.

While the project `sync_status` is `syncing`, the learning list is still filling in. Wait, then call `list_learnings` again. The same `sync_status` and `last_synced_at` are copied onto each learning.

# How Garasu works

What an import stores, how a learning is written, and what the evidence score means.

An experiment is one concluded test. A learning is a product claim, written in plain language, tied to the tests that support it.

### Import an experiment

Call `import_experiment` with the project id and the test.

Send the hypothesis, start date, end date, every variant key, the control key, and raw results. Do not send processed results. Garasu computes lift, p-value, and power from the raw rows.

Each raw row is one metric on one variant. A rate metric needs `users` and `conversions`. A continuous metric needs `users` and `mean`, plus `variance` or `sum_squares` when you have them.

Skip drafts and tests that are still running. A second import of the same experiment returns an error instead of a second copy.

`remove_experiment` deletes that import, its links, and any learning left with no experiments. Confirm with the user first. It cannot be undone.

### Create a learning

After the experiment is stored, Garasu starts a job that writes a learning. The learning is a principle about the product or the customer, not a recap of the test setup, and not advice about how to run the next test.

If the new write-up states the same principle as an older learning, Garasu attaches the experiment to the older learning.

`sync_status` is `syncing` while that job runs, then `idle`.

### Strength of evidence

Each learning has `strength_of_evidence` from 0 to 1.

0 means the linked results do not support the claim. 1 means the linked results support the claim.

Garasu reads each result's post-hoc power, the chance that sample had of detecting the observed effect. A match with low power is weak support. A match with high power is strong support. A flat result with high power can support a claim that the change had no meaningful effect. An inconclusive result with low power supports little. The score ignores how important the idea feels.

The app shows the score as a percent.

| Band | Shown percent |
| --- | --- |
| Weak | 0% to 40% |
| Moderate | 41% to 74% |
| Strong | 75% to 100% |

`list_learnings` sorts by this score, highest first, unless you pass another `order_by`.

# Connect the Garasu MCP

OAuth or an API key, with a setup for each major client.

The server is remote Streamable HTTP.

Server URL: `https://garasu.co/v1/mcp`

Name the server `garasu`.

### OAuth

Paste the URL and leave the API key blank. The client opens Garasu. Sign in and allow access for your organisation.

Grok.com accepts OAuth. It rejects an MCP server that offers an API key and no OAuth.

Codex, Claude, Claude Code, ChatGPT, Cursor, OpenCode, VS Code, and Grok Build can use OAuth when they open a browser. Garasu accepts localhost callbacks, and redirects on grok.com, claude.ai, chatgpt.com, cursor.com, and platform.openai.com.

### API key

Use a key when the machine has no browser, or the client cannot finish the sign-in.

1. [Create an account](https://garasu.co/sign-up) if you need one.
2. Open the [app](https://garasu.co/app) and choose API keys in the sidebar.
3. Create a key and copy it. Treat it like a password.

Send it on every request:

```
Authorization: Bearer YOUR_API_KEY
```

A generic JSON config, for clients that use an `mcpServers` map:

```json
{
  "mcpServers": {
    "garasu": {
      "url": "https://garasu.co/v1/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```

Merge that into the existing `mcpServers` object when the file already has other servers.

### ChatGPT

1. Open ChatGPT and go to Settings → Apps & Connectors (or Plugins).
2. Turn on Developer mode.
3. Create a custom connector and name it Garasu.
4. Paste this as the MCP server URL.

Server URL:

```
https://garasu.co/v1/mcp
```
5. Set authentication to Bearer token. Paste the API key into that field. ChatGPT sends it as this header.

API key:

```
YOUR_API_KEY
```

Authorization header:

```
Authorization: Bearer YOUR_API_KEY
```

The Bearer token is the API key. Do not paste the word Bearer into ChatGPT’s token field.
6. Create the connector, start a new chat, add Garasu from +, then list projects.

### Claude

1. Open Claude on the web or in Claude Desktop.
2. Go to Customize → Connectors (or Settings → Connectors).
3. Click Add custom connector.
4. Name it Garasu and paste this as the remote MCP server URL.

Server URL:

```
https://garasu.co/v1/mcp
```
5. In Advanced settings, add this request header.

API key:

```
YOUR_API_KEY
```

Authorization header:

```
Authorization: Bearer YOUR_API_KEY
```

Claude wants this whole header in Advanced settings, including Authorization: Bearer.
6. Click Add, enable Garasu from Search and tools, then list projects.

### Grok.com

1. Go to grok.com/connectors.
2. Click New Connector, then choose Custom.
3. Name it Garasu and paste this as the server URL. Do not add an API key. Grok.com only accepts OAuth MCP servers.

Server URL:

```
https://garasu.co/v1/mcp
```
4. Click Add Connector. Grok opens Garasu. Sign in and allow access for your organisation.
5. Start a new conversation, enable the Garasu connector, then list projects.

### Grok Bots

1. Open a conversation with your Grok Bot.
2. Send the message below so the bot adds Garasu as a custom MCP server with Bearer auth.

Server URL:

```
https://garasu.co/v1/mcp
```
3. Confirm when the bot asks. If it still needs a key, give it the Authorization header.

API key:

```
YOUR_API_KEY
```

Authorization header:

```
Authorization: Bearer YOUR_API_KEY
```

If the bot asks for a header, paste this whole line.
4. Type @ in chat, attach Garasu, then list projects.

Prompt:

```
Add a custom MCP server called Garasu at https://garasu.co/v1/mcp with header Authorization: Bearer YOUR_API_KEY
```

### Codex

1. Open ~/.codex/config.toml. In the Codex IDE extension, use the gear menu, then MCP settings, then Open config.toml. The CLI reads the same file.
2. For OAuth, add this table. The first tool call opens a browser. Sign in to Garasu and allow your organisation.

OAuth config:

```
[mcp_servers.garasu]
url = "https://garasu.co/v1/mcp"
```
3. For an API key, put the key in GARASU_API_KEY and point Codex at that variable. Codex sends it as Authorization: Bearer.

API key:

```
YOUR_API_KEY
```

API key config:

```
[mcp_servers.garasu]
url = "https://garasu.co/v1/mcp"
bearer_token_env_var = "GARASU_API_KEY"
```
4. In the Codex TUI, run /mcp and confirm garasu is listed. Then ask Codex to list your Garasu projects.

### Claude Code

1. Add the remote server from a terminal. Leave the header off to sign in with OAuth.

OAuth:

```
claude mcp add --transport http garasu https://garasu.co/v1/mcp
```
2. On a machine with no browser, pass the API key as a header.

API key:

```
YOUR_API_KEY
```

API key:

```
claude mcp add --transport http garasu https://garasu.co/v1/mcp --header "Authorization: Bearer YOUR_API_KEY"
```
3. Run /mcp inside Claude Code, enable garasu, then ask it to list projects.

### Grok Build

1. From a terminal, add Garasu over HTTP. The first call can open a browser for OAuth.

OAuth:

```
grok mcp add --transport http garasu https://garasu.co/v1/mcp
```
2. On a headless machine, send the API key as a header instead.

API key:

```
YOUR_API_KEY
```

API key:

```
grok mcp add --transport http garasu https://garasu.co/v1/mcp --header "Authorization: Bearer YOUR_API_KEY"
```
3. Ask Grok Build to call list_projects, then list_learnings for the project you care about.

### OpenCode

1. Edit opencode.json in the project, or ~/.config/opencode/opencode.json if you want it on every project.
2. For OAuth, add the server with no headers. OpenCode opens a browser the first time a tool runs.

OAuth config:

```
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "garasu": {
      "enabled": true,
      "type": "remote",
      "url": "https://garasu.co/v1/mcp"
    }
  }
}
```
3. For an API key, turn OAuth off and send the Bearer header. Otherwise OpenCode tries the browser flow and ignores the key.

API key:

```
YOUR_API_KEY
```

API key config:

```
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "garasu": {
      "enabled": true,
      "type": "remote",
      "url": "https://garasu.co/v1/mcp",
      "oauth": false,
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```
4. Restart OpenCode, then ask it to list Garasu projects.

### Cursor

1. Open Cursor Settings, then MCP, or edit ~/.cursor/mcp.json.
2. For OAuth, add the URL and leave headers out. Cursor opens Garasu so you can sign in.

OAuth config:

```
{
  "mcpServers": {
    "garasu": {
      "url": "https://garasu.co/v1/mcp"
    }
  }
}
```
3. For an API key, add the Authorization header.

API key:

```
YOUR_API_KEY
```

API key config:

```
{
  "mcpServers": {
    "garasu": {
      "url": "https://garasu.co/v1/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```
4. Restart Cursor. In a new agent chat, ask it to list your Garasu projects.

### VS Code

1. Create .vscode/mcp.json in the project.
2. Add Garasu as an HTTP server. Omit headers to use OAuth. Add the header when you want an API key.

OAuth config:

```
{
  "servers": {
    "garasu": {
      "type": "http",
      "url": "https://garasu.co/v1/mcp"
    }
  }
}
```

API key:

```
YOUR_API_KEY
```

API key config:

```
{
  "servers": {
    "garasu": {
      "type": "http",
      "url": "https://garasu.co/v1/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}
```
3. Reload the window. In Copilot chat, enable the garasu tools, then list projects.

# MCP tools

List the projects already in Garasu, then read or search the learnings and experiments stored on one. import_experiment stores a concluded test and starts a learning in the background. is_dupe_experiment checks a proposed spec against experiments already run. remove_experiment undoes one of those imports. Learnings include the project's last_synced_at and sync_status. Wait and list or search again while sync_status is syncing. query_learnings and query_experiments return the closest semantic matches, not the full catalog. Update a project's name, url, or description when they change. Projects themselves are created in the Garasu app.

Each tool name below is its operation id. The function schema is the JSON object an LLM passes to that call.

### Projects

List, read, and update projects.

#### `list_projects`

Operation ID: `list_projects`

List the organization's projects.

When to use: You need a project_id, or you want to see what already exists.

Returns: `{ projects: [{ id, title, description, domain, experiment_count, learning_count, last_synced_at, sync_status, created_at, updated_at, source_url }] }`

No parameters.

Function schema:

```json
{
  "name": "list_projects",
  "description": "List the organization's projects. You need a project_id, or you want to see what already exists.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {}
  }
}
```

Request:

```json
{}
```

Response:

```json
{
  "projects": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "title": "Acme Store",
      "description": "Checkout and pricing experiments.",
      "domain": "store.acme.com",
      "created_at": "2026-03-29T14:12:00.000Z",
      "updated_at": "2026-03-29T15:04:00.000Z",
      "last_synced_at": "2026-03-29T15:04:00.000Z",
      "sync_status": "idle",
      "experiment_count": 1,
      "learning_count": 2,
      "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111"
    }
  ]
}
```

#### `get_project`

Operation ID: `get_project`

Get a project by id, including experiment and learning counts and sync status.

When to use: You have a project id and need its details or counts.

Returns: `{ project: { id, title, description, domain, experiment_count, learning_count, last_synced_at, sync_status, created_at, updated_at, source_url } }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | uuid | Yes | Project id from list_projects. |

Function schema:

```json
{
  "name": "get_project",
  "description": "Get a project by id, including experiment and learning counts and sync status. You have a project id and need its details or counts.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "project_id": {
        "type": "string",
        "format": "uuid",
        "description": "Project id from list_projects."
      }
    },
    "required": [
      "project_id"
    ]
  }
}
```

Request:

```json
{
  "project_id": "11111111-1111-4111-8111-111111111111"
}
```

Response:

```json
{
  "project": {
    "id": "11111111-1111-4111-8111-111111111111",
    "title": "Acme Store",
    "description": "Checkout and pricing experiments.",
    "domain": "store.acme.com",
    "created_at": "2026-03-29T14:12:00.000Z",
    "updated_at": "2026-03-29T15:04:00.000Z",
    "last_synced_at": "2026-03-29T15:04:00.000Z",
    "sync_status": "idle",
    "experiment_count": 1,
    "learning_count": 2,
    "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111"
  }
}
```

#### `update_project`

Operation ID: `update_project`

Update a project's name, url, or description. Omit fields you do not want to change. Pass an empty url to clear it.

When to use: The project exists and the user wants to rename it or change its url.

Returns: `{ project: { id, title, description, domain, experiment_count, learning_count, last_synced_at, sync_status, created_at, updated_at, source_url } }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | uuid | Yes | Project id from list_projects. |
| `name` | string | No | New name. 1–80 characters. |
| `url` | string | No | New url, or an empty string to clear it. Max 255 characters. |
| `description` | string | No | New description. Max 500 characters. |

Function schema:

```json
{
  "name": "update_project",
  "description": "Update a project's name, url, or description. Omit fields you do not want to change. Pass an empty url to clear it. The project exists and the user wants to rename it or change its url.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "project_id": {
        "type": "string",
        "format": "uuid",
        "description": "Project id from list_projects."
      },
      "name": {
        "type": "string",
        "description": "New name. 1–80 characters."
      },
      "url": {
        "type": "string",
        "description": "New url, or an empty string to clear it. Max 255 characters."
      },
      "description": {
        "type": "string",
        "description": "New description. Max 500 characters."
      }
    },
    "required": [
      "project_id"
    ]
  }
}
```

Request:

```json
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "name": "Acme Store",
  "url": "store.acme.com"
}
```

Response:

```json
{
  "project": {
    "id": "11111111-1111-4111-8111-111111111111",
    "title": "Acme Store",
    "description": "Checkout and pricing experiments.",
    "domain": "store.acme.com",
    "created_at": "2026-03-29T14:12:00.000Z",
    "updated_at": "2026-03-29T15:04:00.000Z",
    "last_synced_at": "2026-03-29T15:04:00.000Z",
    "sync_status": "idle",
    "experiment_count": 1,
    "learning_count": 2,
    "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111"
  }
}
```

### Learnings

Search and inspect a project's learnings.

#### `list_learnings`

Operation ID: `list_learnings`

List a project's learnings, strongest evidence first by default. Each learning includes related_experiments plus last_synced_at and sync_status. Wait and list again while sync_status is syncing. Pass nextCursor to fetch the next page.

When to use: You need the learnings in a project, or the next page of that list.

Returns: `{ learnings: [{ id, project_id, title, category, summary, strength_of_evidence, related_experiments, last_synced_at, sync_status, created_at, updated_at, source_url }], nextCursor }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | uuid | Yes | Project id from list_projects. |
| `limit` | integer | No | Page size. Default 50, max 50. |
| `cursor` | string | No | Opaque cursor from the previous page's nextCursor. Omit for the first page. |
| `order_by` | string | No | Sort field. strength_of_evidence (default), created_at, updated_at, or title. |
| `order` | string | No | Sort direction. desc (default) or asc. |

Function schema:

```json
{
  "name": "list_learnings",
  "description": "List a project's learnings, strongest evidence first by default. Each learning includes related_experiments plus last_synced_at and sync_status. Wait and list again while sync_status is syncing. Pass nextCursor to fetch the next page. You need the learnings in a project, or the next page of that list.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "project_id": {
        "type": "string",
        "format": "uuid",
        "description": "Project id from list_projects."
      },
      "limit": {
        "type": "integer",
        "description": "Page size. Default 50, max 50."
      },
      "cursor": {
        "type": "string",
        "description": "Opaque cursor from the previous page's nextCursor. Omit for the first page."
      },
      "order_by": {
        "type": "string",
        "description": "Sort field. strength_of_evidence (default), created_at, updated_at, or title."
      },
      "order": {
        "type": "string",
        "description": "Sort direction. desc (default) or asc."
      }
    },
    "required": [
      "project_id"
    ]
  }
}
```

Request:

```json
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "limit": 50,
  "order_by": "strength_of_evidence",
  "order": "desc"
}
```

Response:

```json
{
  "learnings": [
    {
      "id": "44444444-4444-4444-8444-444444444444",
      "project_id": "11111111-1111-4111-8111-111111111111",
      "title": "Shipping estimates lift checkout completion",
      "category": "Checkout",
      "summary": "Showing an estimated shipping range on cart raised checkout completion. People dropped off when cost appeared for the first time at payment.",
      "strength_of_evidence": 0.72,
      "related_experiments": [
        "22222222-2222-4222-8222-222222222222"
      ],
      "last_synced_at": "2026-03-29T15:04:00.000Z",
      "sync_status": "idle",
      "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/learnings/44444444-4444-4444-8444-444444444444",
      "created_at": "2026-03-29T14:12:00.000Z",
      "updated_at": "2026-03-29T14:12:00.000Z"
    }
  ],
  "nextCursor": null
}
```

#### `get_learning`

Operation ID: `get_learning`

Get a learning by id, including related experiment ids and the project's last_synced_at and sync_status.

When to use: You have a learning_id and need its title, summary, evidence, related experiments, or sync status.

Returns: `{ id, project_id, title, category, summary, strength_of_evidence, related_experiments, last_synced_at, sync_status, created_at, updated_at, source_url }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `learning_id` | uuid | Yes | Learning id from list_learnings or query_learnings. |

Function schema:

```json
{
  "name": "get_learning",
  "description": "Get a learning by id, including related experiment ids and the project's last_synced_at and sync_status. You have a learning_id and need its title, summary, evidence, related experiments, or sync status.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "learning_id": {
        "type": "string",
        "format": "uuid",
        "description": "Learning id from list_learnings or query_learnings."
      }
    },
    "required": [
      "learning_id"
    ]
  }
}
```

Request:

```json
{
  "learning_id": "44444444-4444-4444-8444-444444444444"
}
```

Response:

```json
{
  "id": "44444444-4444-4444-8444-444444444444",
  "project_id": "11111111-1111-4111-8111-111111111111",
  "title": "Shipping estimates lift checkout completion",
  "category": "Checkout",
  "summary": "Showing an estimated shipping range on cart raised checkout completion. People dropped off when cost appeared for the first time at payment.",
  "strength_of_evidence": 0.72,
  "related_experiments": [
    "22222222-2222-4222-8222-222222222222"
  ],
  "last_synced_at": "2026-03-29T15:04:00.000Z",
  "sync_status": "idle",
  "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/learnings/44444444-4444-4444-8444-444444444444",
  "created_at": "2026-03-29T14:12:00.000Z",
  "updated_at": "2026-03-29T14:12:00.000Z"
}
```

#### `query_learnings`

Operation ID: `query_learnings`

Search a project's learnings by semantic similarity. Each learning includes related_experiments plus last_synced_at and sync_status. Wait and search again while sync_status is syncing.

When to use: You need existing learnings related to a question, hypothesis, or idea in this project.

Returns: `{ learnings: [{ id, project_id, title, category, summary, strength_of_evidence, similarity, related_experiments, last_synced_at, sync_status, created_at, updated_at, source_url }] }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | uuid | Yes | Project id from list_projects. |
| `query` | string | Yes | Natural-language search text. 1–2000 characters. |
| `limit` | integer | No | Max learnings to return. Default 10, max 50. |

Function schema:

```json
{
  "name": "query_learnings",
  "description": "Search a project's learnings by semantic similarity. Each learning includes related_experiments plus last_synced_at and sync_status. Wait and search again while sync_status is syncing. You need existing learnings related to a question, hypothesis, or idea in this project.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "project_id": {
        "type": "string",
        "format": "uuid",
        "description": "Project id from list_projects."
      },
      "query": {
        "type": "string",
        "description": "Natural-language search text. 1–2000 characters."
      },
      "limit": {
        "type": "integer",
        "description": "Max learnings to return. Default 10, max 50."
      }
    },
    "required": [
      "project_id",
      "query"
    ]
  }
}
```

Request:

```json
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "query": "shipping cost transparency at checkout",
  "limit": 10
}
```

Response:

```json
{
  "learnings": [
    {
      "id": "44444444-4444-4444-8444-444444444444",
      "project_id": "11111111-1111-4111-8111-111111111111",
      "title": "Shipping estimates lift checkout completion",
      "category": "Checkout",
      "summary": "Showing an estimated shipping range on cart raised checkout completion. People dropped off when cost appeared for the first time at payment.",
      "strength_of_evidence": 0.72,
      "related_experiments": [
        "22222222-2222-4222-8222-222222222222"
      ],
      "last_synced_at": "2026-03-29T15:04:00.000Z",
      "sync_status": "idle",
      "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/learnings/44444444-4444-4444-8444-444444444444",
      "created_at": "2026-03-29T14:12:00.000Z",
      "updated_at": "2026-03-29T14:12:00.000Z",
      "similarity": 0.86
    }
  ]
}
```

### Experiments

Import, check, remove, list, read, and search a project's experiments.

#### `import_experiment`

Operation ID: `import_experiment`

Add a concluded experiment. Embeds the title and hypothesis, stores the experiment, and starts a learning extraction job. Do not send processed_results; Garasu computes them from raw_results.

When to use: You have a concluded test with results and want it stored on a project. Skip drafts and tests that are still running.

Returns: `{ experiment_id, experiment }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | uuid | Yes | Project id from list_projects. |
| `experiment` | object | Yes | The concluded experiment to store. Garasu computes processed_results. |

`experiment` fields:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No | Display title. Max 200 characters. When omitted, Garasu uses the first 200 characters of the hypothesis. |
| `hypothesis` | string | Yes | What was tested and why. 1–8000 characters. |
| `start_date` | string | Yes | When the test started, as ISO 8601. |
| `end_date` | string | Yes | When the test ended, as ISO 8601. Must be on or after start_date. |
| `variant_keys` | string[] | Yes | Every arm, including the control. At least two unique keys. |
| `control_variant_key` | string | Yes | The control arm. Must be one of variant_keys. |
| `raw_results` | object[] | Yes | One row per metric per variant. At least two. Each row needs metric, variant_key, users, and conversions or mean. |
| `metadata` | object | No | Source details, such as source and source_id. Defaults to {}. |
| `conclusion` | string | No | Outcome label, such as won, lost, or inconclusive. Max 40 characters. |
| `conclusion_summary` | string | No | Short write-up of the outcome. Max 8000 characters. |
| `winning_variant` | string | No | Winning arm, when the source named one. Max 80 characters. |

`experiment.raw_results[]` fields:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `metric` | string | Yes | Metric name. Max 120 characters. |
| `variant_key` | string | Yes | Arm this row belongs to. Must be one of variant_keys. |
| `users` | integer | Yes | Sample size. Must be greater than 0. |
| `conversions` | integer | No | Conversion count for a rate metric. Cannot exceed users. |
| `mean` | number | No | Observed mean for a continuous metric. Required when conversions is omitted. |
| `variance` | number | No | Sample variance of the per-user metric. Preferred for mean metrics. |
| `sum_squares` | number | No | Sum of squares of the per-user metric. Used when variance is omitted. |

Function schema:

```json
{
  "name": "import_experiment",
  "description": "Add a concluded experiment. Embeds the title and hypothesis, stores the experiment, and starts a learning extraction job. Do not send processed_results; Garasu computes them from raw_results. You have a concluded test with results and want it stored on a project. Skip drafts and tests that are still running.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "project_id": {
        "type": "string",
        "format": "uuid",
        "description": "Project id from list_projects."
      },
      "experiment": {
        "type": "object",
        "description": "The concluded experiment to store. Garasu computes processed_results.",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "description": "Display title. Max 200 characters. When omitted, Garasu uses the first 200 characters of the hypothesis."
          },
          "hypothesis": {
            "type": "string",
            "description": "What was tested and why. 1–8000 characters."
          },
          "start_date": {
            "type": "string",
            "description": "When the test started, as ISO 8601."
          },
          "end_date": {
            "type": "string",
            "description": "When the test ended, as ISO 8601. Must be on or after start_date."
          },
          "variant_keys": {
            "type": "array",
            "description": "Every arm, including the control. At least two unique keys.",
            "items": {
              "type": "string"
            }
          },
          "control_variant_key": {
            "type": "string",
            "description": "The control arm. Must be one of variant_keys."
          },
          "raw_results": {
            "type": "array",
            "description": "One row per metric per variant. At least two. Each row needs metric, variant_key, users, and conversions or mean.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "metric": {
                  "type": "string",
                  "description": "Metric name. Max 120 characters."
                },
                "variant_key": {
                  "type": "string",
                  "description": "Arm this row belongs to. Must be one of variant_keys."
                },
                "users": {
                  "type": "integer",
                  "description": "Sample size. Must be greater than 0."
                },
                "conversions": {
                  "type": "integer",
                  "description": "Conversion count for a rate metric. Cannot exceed users."
                },
                "mean": {
                  "type": "number",
                  "description": "Observed mean for a continuous metric. Required when conversions is omitted."
                },
                "variance": {
                  "type": "number",
                  "description": "Sample variance of the per-user metric. Preferred for mean metrics."
                },
                "sum_squares": {
                  "type": "number",
                  "description": "Sum of squares of the per-user metric. Used when variance is omitted."
                }
              },
              "required": [
                "metric",
                "variant_key",
                "users"
              ]
            }
          },
          "metadata": {
            "type": "object",
            "description": "Source details, such as source and source_id. Defaults to {}.",
            "additionalProperties": true,
            "properties": {}
          },
          "conclusion": {
            "type": "string",
            "description": "Outcome label, such as won, lost, or inconclusive. Max 40 characters."
          },
          "conclusion_summary": {
            "type": "string",
            "description": "Short write-up of the outcome. Max 8000 characters."
          },
          "winning_variant": {
            "type": "string",
            "description": "Winning arm, when the source named one. Max 80 characters."
          }
        },
        "required": [
          "hypothesis",
          "start_date",
          "end_date",
          "variant_keys",
          "control_variant_key",
          "raw_results"
        ]
      }
    },
    "required": [
      "project_id",
      "experiment"
    ]
  }
}
```

Request:

```json
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "experiment": {
    "name": "Cart shipping estimate",
    "hypothesis": "If we show an estimated shipping range on cart, checkout completion will go up because people stop getting surprised by cost at payment.",
    "start_date": "2026-03-01T00:00:00.000Z",
    "end_date": "2026-03-28T00:00:00.000Z",
    "variant_keys": [
      "control",
      "estimate"
    ],
    "control_variant_key": "control",
    "raw_results": [
      {
        "metric": "Checkout completion",
        "variant_key": "control",
        "users": 24105,
        "conversions": 822
      },
      {
        "metric": "Checkout completion",
        "variant_key": "estimate",
        "users": 24105,
        "conversions": 882
      }
    ],
    "metadata": {
      "source": "posthog",
      "source_id": "cart-shipping-estimate"
    }
  }
}
```

Response:

```json
{
  "experiment_id": "22222222-2222-4222-8222-222222222222",
  "experiment": {
    "id": "22222222-2222-4222-8222-222222222222",
    "project_id": "11111111-1111-4111-8111-111111111111",
    "name": "Cart shipping estimate",
    "hypothesis": "If we show an estimated shipping range on cart, checkout completion will go up because people stop getting surprised by cost at payment.",
    "start_date": "2026-03-01",
    "end_date": "2026-03-28",
    "variant_keys": [
      "control",
      "estimate"
    ],
    "control_variant_key": "control",
    "metadata": {
      "source": "posthog",
      "source_id": "cart-shipping-estimate"
    },
    "headline": {
      "metric": "Checkout completion",
      "variant_key": "estimate",
      "lift_relative": 7.2993,
      "p_value": 0.1389,
      "control_n": 24105,
      "variant_n": 24105
    },
    "processed_results": [
      {
        "metric": "Checkout completion",
        "variant_key": "estimate",
        "control_variant_key": "control",
        "control_n": 24105,
        "variant_n": 24105,
        "control_mean": 0.034101,
        "variant_mean": 0.03659,
        "lift_absolute": 0.002489,
        "lift_relative": 7.2993,
        "p_value": 0.1389,
        "z_score": 1.4799,
        "post_hoc_power": 32,
        "mde80_relative": 13.8182,
        "kind": "rate",
        "control_variance": 0.032939,
        "variant_variance": 0.035251
      }
    ],
    "related_learning_ids": [],
    "related_learnings": [],
    "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/experiments/22222222-2222-4222-8222-222222222222",
    "created_at": "2026-03-29T14:12:00.000Z",
    "updated_at": "2026-03-29T14:12:00.000Z",
    "raw_results": [
      {
        "metric": "Checkout completion",
        "variant_key": "control",
        "users": 24105,
        "conversions": 822
      },
      {
        "metric": "Checkout completion",
        "variant_key": "estimate",
        "users": 24105,
        "conversions": 882
      }
    ]
  }
}
```

#### `remove_experiment`

Operation ID: `remove_experiment`

Undo one import_experiment. Deletes that experiment, its joins, and any learning left with no experiments. Cannot be undone.

When to use: An import_experiment call stored the wrong experiment and you need to remove it. Not for clearing a project.

Returns: `{ experiment_id, removed_learning_ids }`

Confirm with the user before calling this. It cannot be undone.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `experiment_id` | uuid | Yes | Experiment id returned by import_experiment. |

Function schema:

```json
{
  "name": "remove_experiment",
  "description": "Undo one import_experiment. Deletes that experiment, its joins, and any learning left with no experiments. Cannot be undone. An import_experiment call stored the wrong experiment and you need to remove it. Not for clearing a project.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "experiment_id": {
        "type": "string",
        "format": "uuid",
        "description": "Experiment id returned by import_experiment."
      }
    },
    "required": [
      "experiment_id"
    ]
  }
}
```

Request:

```json
{
  "experiment_id": "22222222-2222-4222-8222-222222222222"
}
```

Response:

```json
{
  "experiment_id": "22222222-2222-4222-8222-222222222222",
  "removed_learning_ids": [
    "44444444-4444-4444-8444-444444444444"
  ]
}
```

#### `list_experiments`

Operation ID: `list_experiments`

List a project's experiments. Each row includes processed results, a headline, and related learnings. Pass nextCursor to fetch the next page.

When to use: You need the experiments in a project, or the next page of that list.

Returns: `{ experiments: [{ id, project_id, name, hypothesis, start_date, end_date, variant_keys, control_variant_key, metadata, headline, processed_results, related_learning_ids, related_learnings, created_at, updated_at, source_url }], nextCursor }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | uuid | Yes | Project id from list_projects. |
| `limit` | integer | No | Page size. Default 50, max 50. |
| `cursor` | string | No | Opaque cursor from the previous page's nextCursor. Omit for the first page. |
| `order_by` | string | No | Sort field. created_at (default), updated_at, start_date, end_date, or name. |
| `order` | string | No | Sort direction. desc (default) or asc. |

Function schema:

```json
{
  "name": "list_experiments",
  "description": "List a project's experiments. Each row includes processed results, a headline, and related learnings. Pass nextCursor to fetch the next page. You need the experiments in a project, or the next page of that list.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "project_id": {
        "type": "string",
        "format": "uuid",
        "description": "Project id from list_projects."
      },
      "limit": {
        "type": "integer",
        "description": "Page size. Default 50, max 50."
      },
      "cursor": {
        "type": "string",
        "description": "Opaque cursor from the previous page's nextCursor. Omit for the first page."
      },
      "order_by": {
        "type": "string",
        "description": "Sort field. created_at (default), updated_at, start_date, end_date, or name."
      },
      "order": {
        "type": "string",
        "description": "Sort direction. desc (default) or asc."
      }
    },
    "required": [
      "project_id"
    ]
  }
}
```

Request:

```json
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "limit": 50,
  "order_by": "created_at",
  "order": "desc"
}
```

Response:

```json
{
  "experiments": [
    {
      "id": "22222222-2222-4222-8222-222222222222",
      "project_id": "11111111-1111-4111-8111-111111111111",
      "name": "Cart shipping estimate",
      "hypothesis": "If we show an estimated shipping range on cart, checkout completion will go up because people stop getting surprised by cost at payment.",
      "start_date": "2026-03-01",
      "end_date": "2026-03-28",
      "variant_keys": [
        "control",
        "estimate"
      ],
      "control_variant_key": "control",
      "metadata": {
        "source": "posthog",
        "source_id": "cart-shipping-estimate"
      },
      "headline": {
        "metric": "Checkout completion",
        "variant_key": "estimate",
        "lift_relative": 7.2993,
        "p_value": 0.1389,
        "control_n": 24105,
        "variant_n": 24105
      },
      "processed_results": [
        {
          "metric": "Checkout completion",
          "variant_key": "estimate",
          "control_variant_key": "control",
          "control_n": 24105,
          "variant_n": 24105,
          "control_mean": 0.034101,
          "variant_mean": 0.03659,
          "lift_absolute": 0.002489,
          "lift_relative": 7.2993,
          "p_value": 0.1389,
          "z_score": 1.4799,
          "post_hoc_power": 32,
          "mde80_relative": 13.8182,
          "kind": "rate",
          "control_variance": 0.032939,
          "variant_variance": 0.035251
        }
      ],
      "related_learning_ids": [
        "44444444-4444-4444-8444-444444444444",
        "55555555-5555-4555-8555-555555555555"
      ],
      "related_learnings": [
        {
          "id": "44444444-4444-4444-8444-444444444444",
          "title": "Shipping estimates lift checkout completion",
          "summary": "Showing an estimated shipping range on cart raised checkout completion. People dropped off when cost appeared for the first time at payment.",
          "strength_of_evidence": 0.72,
          "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/learnings/44444444-4444-4444-8444-444444444444"
        }
      ],
      "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/experiments/22222222-2222-4222-8222-222222222222",
      "created_at": "2026-03-29T14:12:00.000Z",
      "updated_at": "2026-03-29T14:12:00.000Z"
    }
  ],
  "nextCursor": null
}
```

#### `query_experiments`

Operation ID: `query_experiments`

Search a project's experiments by semantic similarity of the title and hypothesis. Returns the closest matches, not a full catalog.

When to use: You need experiments in this project related to a question or hypothesis. This is a search, not a full catalog, and it has no cursor.

Returns: `{ experiments: [{ id, project_id, name, hypothesis, start_date, end_date, variant_keys, control_variant_key, metadata, headline, processed_results, related_learning_ids, related_learnings, similarity, created_at, updated_at, source_url }] }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | uuid | Yes | Project id from list_projects. |
| `query` | string | Yes | Natural-language search text. 1–2000 characters. |
| `limit` | integer | No | Max experiments to return. Default 10, max 50. |

Function schema:

```json
{
  "name": "query_experiments",
  "description": "Search a project's experiments by semantic similarity of the title and hypothesis. Returns the closest matches, not a full catalog. You need experiments in this project related to a question or hypothesis. This is a search, not a full catalog, and it has no cursor.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "project_id": {
        "type": "string",
        "format": "uuid",
        "description": "Project id from list_projects."
      },
      "query": {
        "type": "string",
        "description": "Natural-language search text. 1–2000 characters."
      },
      "limit": {
        "type": "integer",
        "description": "Max experiments to return. Default 10, max 50."
      }
    },
    "required": [
      "project_id",
      "query"
    ]
  }
}
```

Request:

```json
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "query": "shipping estimate",
  "limit": 10
}
```

Response:

```json
{
  "experiments": [
    {
      "id": "22222222-2222-4222-8222-222222222222",
      "project_id": "11111111-1111-4111-8111-111111111111",
      "name": "Cart shipping estimate",
      "hypothesis": "If we show an estimated shipping range on cart, checkout completion will go up because people stop getting surprised by cost at payment.",
      "start_date": "2026-03-01",
      "end_date": "2026-03-28",
      "variant_keys": [
        "control",
        "estimate"
      ],
      "control_variant_key": "control",
      "metadata": {
        "source": "posthog",
        "source_id": "cart-shipping-estimate"
      },
      "headline": {
        "metric": "Checkout completion",
        "variant_key": "estimate",
        "lift_relative": 7.2993,
        "p_value": 0.1389,
        "control_n": 24105,
        "variant_n": 24105
      },
      "processed_results": [
        {
          "metric": "Checkout completion",
          "variant_key": "estimate",
          "control_variant_key": "control",
          "control_n": 24105,
          "variant_n": 24105,
          "control_mean": 0.034101,
          "variant_mean": 0.03659,
          "lift_absolute": 0.002489,
          "lift_relative": 7.2993,
          "p_value": 0.1389,
          "z_score": 1.4799,
          "post_hoc_power": 32,
          "mde80_relative": 13.8182,
          "kind": "rate",
          "control_variance": 0.032939,
          "variant_variance": 0.035251
        }
      ],
      "related_learning_ids": [
        "44444444-4444-4444-8444-444444444444",
        "55555555-5555-4555-8555-555555555555"
      ],
      "related_learnings": [
        {
          "id": "44444444-4444-4444-8444-444444444444",
          "title": "Shipping estimates lift checkout completion",
          "summary": "Showing an estimated shipping range on cart raised checkout completion. People dropped off when cost appeared for the first time at payment.",
          "strength_of_evidence": 0.72,
          "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/learnings/44444444-4444-4444-8444-444444444444"
        }
      ],
      "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/experiments/22222222-2222-4222-8222-222222222222",
      "created_at": "2026-03-29T14:12:00.000Z",
      "updated_at": "2026-03-29T14:12:00.000Z",
      "similarity": 0.84
    }
  ]
}
```

#### `is_dupe_experiment`

Operation ID: `is_dupe_experiment`

Check whether a proposed experiment has already been run in this project. Embeds the name and hypothesis, then Jev scores the nearest stored experiments. Returns only those Jev scores above 0.9, most similar first.

When to use: You have a new experiment spec and need to know if this project already ran it. An empty list means it has not been run.

Returns: `{ experiments: [{ id, project_id, name, hypothesis, start_date, end_date, variant_keys, control_variant_key, metadata, headline, processed_results, related_learning_ids, related_learnings, similarity, created_at, updated_at, source_url }] }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `project_id` | uuid | Yes | Project id from list_projects. |
| `experiment_spec` | object | Yes | The proposed experiment. The embedding uses name and hypothesis. Jev also reads content when you send it. |

`experiment_spec` fields:

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | Display title. Max 200 characters. title is accepted as an alias. |
| `hypothesis` | string | Yes | What the test would change and why. 1–8000 characters. |
| `content` | string | No | Optional fuller spec, such as variants and the primary metric. Max 12000 characters. |

Function schema:

```json
{
  "name": "is_dupe_experiment",
  "description": "Check whether a proposed experiment has already been run in this project. Embeds the name and hypothesis, then Jev scores the nearest stored experiments. Returns only those Jev scores above 0.9, most similar first. You have a new experiment spec and need to know if this project already ran it. An empty list means it has not been run.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "project_id": {
        "type": "string",
        "format": "uuid",
        "description": "Project id from list_projects."
      },
      "experiment_spec": {
        "type": "object",
        "description": "The proposed experiment. The embedding uses name and hypothesis. Jev also reads content when you send it.",
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "description": "Display title. Max 200 characters. title is accepted as an alias."
          },
          "hypothesis": {
            "type": "string",
            "description": "What the test would change and why. 1–8000 characters."
          },
          "content": {
            "type": "string",
            "description": "Optional fuller spec, such as variants and the primary metric. Max 12000 characters."
          }
        },
        "required": [
          "name",
          "hypothesis"
        ]
      }
    },
    "required": [
      "project_id",
      "experiment_spec"
    ]
  }
}
```

Request:

```json
{
  "project_id": "11111111-1111-4111-8111-111111111111",
  "experiment_spec": {
    "name": "Cart shipping estimate",
    "hypothesis": "If we show an estimated shipping range on cart, checkout completion will go up because people stop getting surprised by cost at payment."
  }
}
```

Response:

```json
{
  "experiments": [
    {
      "id": "22222222-2222-4222-8222-222222222222",
      "project_id": "11111111-1111-4111-8111-111111111111",
      "name": "Cart shipping estimate",
      "hypothesis": "If we show an estimated shipping range on cart, checkout completion will go up because people stop getting surprised by cost at payment.",
      "start_date": "2026-03-01",
      "end_date": "2026-03-28",
      "variant_keys": [
        "control",
        "estimate"
      ],
      "control_variant_key": "control",
      "metadata": {
        "source": "posthog",
        "source_id": "cart-shipping-estimate"
      },
      "headline": {
        "metric": "Checkout completion",
        "variant_key": "estimate",
        "lift_relative": 7.2993,
        "p_value": 0.1389,
        "control_n": 24105,
        "variant_n": 24105
      },
      "processed_results": [
        {
          "metric": "Checkout completion",
          "variant_key": "estimate",
          "control_variant_key": "control",
          "control_n": 24105,
          "variant_n": 24105,
          "control_mean": 0.034101,
          "variant_mean": 0.03659,
          "lift_absolute": 0.002489,
          "lift_relative": 7.2993,
          "p_value": 0.1389,
          "z_score": 1.4799,
          "post_hoc_power": 32,
          "mde80_relative": 13.8182,
          "kind": "rate",
          "control_variance": 0.032939,
          "variant_variance": 0.035251
        }
      ],
      "related_learning_ids": [
        "44444444-4444-4444-8444-444444444444",
        "55555555-5555-4555-8555-555555555555"
      ],
      "related_learnings": [
        {
          "id": "44444444-4444-4444-8444-444444444444",
          "title": "Shipping estimates lift checkout completion",
          "summary": "Showing an estimated shipping range on cart raised checkout completion. People dropped off when cost appeared for the first time at payment.",
          "strength_of_evidence": 0.72,
          "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/learnings/44444444-4444-4444-8444-444444444444"
        }
      ],
      "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/experiments/22222222-2222-4222-8222-222222222222",
      "created_at": "2026-03-29T14:12:00.000Z",
      "updated_at": "2026-03-29T14:12:00.000Z",
      "similarity": 0.94
    }
  ]
}
```

#### `get_experiment`

Operation ID: `get_experiment`

Get an experiment by id.

When to use: You have an experiment_id and need the saved experiment, including raw results.

Returns: `{ id, project_id, name, hypothesis, start_date, end_date, variant_keys, control_variant_key, metadata, headline, processed_results, related_learning_ids, related_learnings, raw_results, created_at, updated_at, source_url }`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `experiment_id` | uuid | Yes | Experiment id from import_experiment, list_experiments, or query_experiments. |

Function schema:

```json
{
  "name": "get_experiment",
  "description": "Get an experiment by id. You have an experiment_id and need the saved experiment, including raw results.",
  "parameters": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
      "experiment_id": {
        "type": "string",
        "format": "uuid",
        "description": "Experiment id from import_experiment, list_experiments, or query_experiments."
      }
    },
    "required": [
      "experiment_id"
    ]
  }
}
```

Request:

```json
{
  "experiment_id": "22222222-2222-4222-8222-222222222222"
}
```

Response:

```json
{
  "id": "22222222-2222-4222-8222-222222222222",
  "project_id": "11111111-1111-4111-8111-111111111111",
  "name": "Cart shipping estimate",
  "hypothesis": "If we show an estimated shipping range on cart, checkout completion will go up because people stop getting surprised by cost at payment.",
  "start_date": "2026-03-01",
  "end_date": "2026-03-28",
  "variant_keys": [
    "control",
    "estimate"
  ],
  "control_variant_key": "control",
  "metadata": {
    "source": "posthog",
    "source_id": "cart-shipping-estimate"
  },
  "headline": {
    "metric": "Checkout completion",
    "variant_key": "estimate",
    "lift_relative": 7.2993,
    "p_value": 0.1389,
    "control_n": 24105,
    "variant_n": 24105
  },
  "processed_results": [
    {
      "metric": "Checkout completion",
      "variant_key": "estimate",
      "control_variant_key": "control",
      "control_n": 24105,
      "variant_n": 24105,
      "control_mean": 0.034101,
      "variant_mean": 0.03659,
      "lift_absolute": 0.002489,
      "lift_relative": 7.2993,
      "p_value": 0.1389,
      "z_score": 1.4799,
      "post_hoc_power": 32,
      "mde80_relative": 13.8182,
      "kind": "rate",
      "control_variance": 0.032939,
      "variant_variance": 0.035251
    }
  ],
  "related_learning_ids": [
    "44444444-4444-4444-8444-444444444444",
    "55555555-5555-4555-8555-555555555555"
  ],
  "related_learnings": [
    {
      "id": "44444444-4444-4444-8444-444444444444",
      "title": "Shipping estimates lift checkout completion",
      "summary": "Showing an estimated shipping range on cart raised checkout completion. People dropped off when cost appeared for the first time at payment.",
      "strength_of_evidence": 0.72,
      "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/learnings/44444444-4444-4444-8444-444444444444"
    }
  ],
  "source_url": "https://garasu.co/app/77777777-7777-4777-8777-777777777777/projects/11111111-1111-4111-8111-111111111111/experiments/22222222-2222-4222-8222-222222222222",
  "created_at": "2026-03-29T14:12:00.000Z",
  "updated_at": "2026-03-29T14:12:00.000Z",
  "raw_results": [
    {
      "metric": "Checkout completion",
      "variant_key": "control",
      "users": 24105,
      "conversions": 822
    },
    {
      "metric": "Checkout completion",
      "variant_key": "estimate",
      "users": 24105,
      "conversions": 882
    }
  ]
}
```
