> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revdesk.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimize

> Run website tests from your own systems: create tests, read results, record conversions, and hear about winners over webhooks.

Optimize runs A/B tests on your website through one tag. The API lets you do from your
own systems everything the app does: create a test on a page, start and pause it, read its
results, ship the winner, and record conversions the tag cannot see (a closed order, a signed
contract). Webhooks tell you when a test starts, finds a winner, or ships.

## Install the tag

```bash theme={null}
curl https://api.revdesk.com/v1/optimize/snippet \
  -H "Authorization: Bearer $REVDESK_API_KEY"
# → { "data": { "property_id": "…", "public_key": "…", "script_tag": "<script src=\"…\" data-key=\"…\" async></script>" } }
```

Paste `script_tag` into the `<head>` of every page you want to test. The property is verified the
first time the tag loads from the registered domain; `GET /v1/optimize/properties` shows `verified_at`.

## Endpoints

All endpoints take the `optimize:read` scope for reads and `optimize:write` for changes.

| Method   | Path                              | What it does                                                        |
| -------- | --------------------------------- | ------------------------------------------------------------------- |
| `GET`    | `/v1/optimize/tests`              | List tests, filter by `status`, page with `limit` and `offset`.     |
| `POST`   | `/v1/optimize/tests`              | Create a test on one page with variants; `start: true` starts it.   |
| `GET`    | `/v1/optimize/tests/{id}`         | One test with its goal and variants.                                |
| `PATCH`  | `/v1/optimize/tests/{id}`         | Edit name, hypothesis, page, traffic split; `status` starts/pauses. |
| `DELETE` | `/v1/optimize/tests/{id}`         | Archive. Results and shipped changes are kept.                      |
| `POST`   | `/v1/optimize/tests/{id}/ship`    | Make a variant permanent and retire the test.                       |
| `GET`    | `/v1/optimize/tests/{id}/results` | Per-variant impressions, conversions, lift, significance, value.    |
| `GET`    | `/v1/optimize/conversions`        | Conversions recorded for a test.                                    |
| `POST`   | `/v1/optimize/conversions`        | Record a conversion from your own systems.                          |
| `GET`    | `/v1/optimize/properties`         | The workspace's websites and whether the tag has been seen.         |
| `GET`    | `/v1/optimize/snippet`            | The script tag to install.                                          |

## Create and start a test

A test is a page, a goal, and one or more variants. Each variant is a list of DOM operations the
tag applies for the visitors bucketed into it: `setText`, `setAttribute`, `addClass`,
`removeClass`, `setStyle`, `hide`, and `replaceHref`. Nothing in the list can introduce script.

```bash theme={null}
curl -X POST https://api.revdesk.com/v1/optimize/tests \
  -H "Authorization: Bearer $REVDESK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pricing headline",
    "page_url": "/pricing",
    "goal": { "type": "form_submit", "selector": "form#lead" },
    "variants": [
      { "name": "Outcome first", "ops": [{ "op": "setText", "selector": "h1", "value": "Close more deals this month" }] }
    ],
    "start": true
  }'
```

Goal types: `form_submit`, `tel_click`, `cta_click`, `selector_click` (each takes a `selector`),
and `url_visit` (takes `url_match_type` and `url_pattern`). `traffic_split` (0.05 to 1) is the
share of visitors enrolled; the rest see the page untouched.

## Record a conversion

The tag counts goals it can see on the page. For outcomes that happen elsewhere, send them in.
Include the tag's `visitor_id` (the `rd_sid` cookie, or `window.rdSite.visitorId`) so the
conversion is credited to the arm that visitor saw.

```bash theme={null}
curl -X POST https://api.revdesk.com/v1/optimize/conversions \
  -H "Authorization: Bearer $REVDESK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "test_id": "…", "visitor_id": "0123456789abcdef0123456789abcdef", "value": 249.99, "metadata": { "order_id": "ord_42" } }'
# → { "data": { "recorded": true, "test_id": "…", "variant_id": "…" } }
```

`metadata.order_id` makes the write idempotent: a repeat returns `recorded: false`. `value` is in
major units and defaults to USD; it shows up as `revenue_cents` per variant in results.

## Read results

```bash theme={null}
curl https://api.revdesk.com/v1/optimize/tests/{id}/results \
  -H "Authorization: Bearer $REVDESK_API_KEY"
```

`variants[]` carries `impressions`, `conversions`, `conversion_rate`, `lift`, `p_value`,
`probability_to_beat_control`, and `revenue_cents`. `decision.reason` is one of `winner`,
`collecting`, `no_difference`, or `inconclusive`; `decision.winner_variant_id` is set only for
`winner`. `daily[]` is a per-variant, per-day series for charts.

## Events

Subscribe with [webhooks](/api-reference/webhooks). Site events are delivered flat and carry the
event name in the body:

| `event_type`                  | Fires when                                                        |
| ----------------------------- | ----------------------------------------------------------------- |
| `optimize.test.created`       | A test was created.                                               |
| `optimize.test.started`       | A test started or resumed serving variants.                       |
| `optimize.test.completed`     | A test finished without a winner being declared.                  |
| `optimize.test.winner`        | A test finished with a winner. `test.winner_variant_id` names it. |
| `optimize.test.shipped`       | A variant was made permanent on the page.                         |
| `optimize.conversion.created` | A conversion was recorded through the API.                        |

```json theme={null}
{
  "event": "optimize.test.winner",
  "occurred_at": "2026-09-09T12:00:00.000Z",
  "test": {
    "id": "…",
    "name": "Pricing headline",
    "status": "completed",
    "page_url": "/pricing",
    "winner_variant_id": "…",
    "variants": [{ "id": "…", "name": "Control", "is_control": true, "weight": 1, "ops": [], "redirect_url": null }]
  }
}
```

`optimize.conversion.created` carries `conversion` instead of `test`, in the same shape as
`GET /v1/optimize/conversions`.
