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

# Analytics and attribution

> Define what success means for an initiative, then measure against it.

Boom does not decide what a good outcome is for you. You define it, per
initiative, and everything else is measured against that definition: a rate, a
value, a funnel, and the list of individual conversations that counted.

<Note>
  Success metrics can be configured from the app or [over the API and
  MCP](#configuring-metrics-over-the-api). The analytics **views** — the funnel,
  the per node numbers, the charts — are read in the app only. The raw material
  behind them is on the API: [extracted values](/extraction), transcripts and
  participant records all come back, so you can compute your own numbers if you
  would rather.
</Note>

## Defining success

An initiative can carry more than one named success metric. Each one says what
signal counts as success, and how to aggregate it.

Three kinds of signal:

| Signal | Counts success when | Use it for |
| - | - | - |
| A **CDP event** | A named event lands for that person inside the attribution window. The value can come from a property on the event, or from an object the event points at, such as the total on the order it references. | A signup, a payment, a booking, an order. |
| A **CDP object** | An object reached from the person exists, dated inside the window by one of its own attributes rather than by when Boom saw it. | An order, a subscription, an application. |
| An **extracted variable** | The conversation produced a value for a field in your [extraction schema](/extraction). | Outcomes that only exist because someone said them, like agreeing to come back. |

Each metric aggregates as a **count**, a **sum**, an **average** or a **max**, so
"how many came back" and "how much revenue came back" are the same mechanism with
a different aggregation.

### The attribution window

A conversation's window opens when Boom sends its first outbound message and
closes 48 hours after the journey ends. That grace period is fixed and not
configurable today, so a purchase two weeks later is not attributed, by design.

A person Boom never messaged has no window at all, and is excluded from both the
numerator and the denominator rather than counted as a failure.

## Configuring metrics over the API

The same definitions the app's dialog writes are readable and settable
programmatically, on an initiative you already have the id for.

<Tabs>
  <Tab title="MCP">
    * `success_metrics_catalog` — what a metric can point at
    * `success_metrics_list` — the metrics on an initiative
    * `success_metrics_upsert` — add one, or replace one by `rootId`
    * `success_metrics_delete` — retire one
  </Tab>

  <Tab title="REST">
    * `GET /api/v1/initiatives/{id}/success-metrics/catalog`
    * `GET /api/v1/initiatives/{id}/success-metrics`
    * `POST /api/v1/initiatives/{id}/success-metrics`
    * `DELETE /api/v1/initiatives/{id}/success-metrics/{rootId}`
  </Tab>
</Tabs>

### Start with the catalog

An event name, object type or variable that does not exist is **accepted and
then matches nothing**, so the metric quietly reports zero rather than failing.
Ask what is available first:

```bash theme={null}
curl "https://www.useboom.ai/api/v1/initiatives/init_123/success-metrics/catalog" \
  -H "Authorization: Bearer $BOOM_KEY"
```

You get `events`, `objectTypes` and `variables` for this initiative
(`variables` leaves out archived guiding questions, which collect no new
answers). Add
`?eventName=order_completed` for that event's properties, or
`?objectTypeId=...` for a type's attributes and the paths that link it to a
person; both come back `null` when you did not ask for them.

### Setting a metric

```bash theme={null}
curl -X POST "https://www.useboom.ai/api/v1/initiatives/init_123/success-metrics" \
  -H "Authorization: Bearer $BOOM_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Revenue recovered",
    "signalType": "CDP_EVENT",
    "eventName": "order_completed",
    "aggregation": "SUM",
    "valueProperty": "total"
  }'
```

```json theme={null}
{
  "rootId": "sdr_abc123",
  "version": 1,
  "status": "ACTIVE",
  "name": "Revenue recovered",
  "signalType": "CDP_EVENT",
  "eventName": "order_completed",
  "aggregation": "SUM",
  "valueProperty": "total",
  "valueSource": "EVENT_PROPERTY",
  "variableId": null,
  "objectTypeId": null,
  "windowHours": 48,
  "createdAt": "2026-09-18T10:00:00.000Z"
}
```

Abridged: the response always carries every configuration field, `null` for the
ones this signal type does not use.

Omit `rootId` to add a metric; pass an existing metric's `rootId` to replace
it, which files a new `version` under the same `rootId`. `rootId` is the id to
hold on to — `version` counts *the initiative's* definition history, not this
metric's, so a brand new metric on an initiative that already has one starts
above `1`. **Replacing is not a patch** — send the metric's complete
configuration, because fields you leave out are cleared rather than kept.

Which fields are required depends on `signalType` and `aggregation`: a `COUNT`
needs no value field, while `SUM`, `AVERAGE` and `MAX` each need one, and a
missing one is rejected with a `validation_failed` error naming the field.

`GET /api/v1/initiatives/{id}/success-metrics` returns the metrics in the exact
shape `POST` accepts, so you can read one, change a field and send it back. It
returns the ACTIVE ones by default; `?status=all` adds the superseded versions,
newest first, which is the edit history. An initiative with nothing configured
returns an empty list, not a 404.

### Retiring a metric

```bash theme={null}
curl -X DELETE "https://www.useboom.ai/api/v1/initiatives/init_123/success-metrics/sdr_abc123" \
  -H "Authorization: Bearer $BOOM_KEY"
```

The metric leaves the dashboard immediately. Its configuration is kept for the
audit trail — `?status=all` still lists it as `SUPERSEDED` — and posting the
same `rootId` again brings it back. Removing the last metric returns the
initiative to having no success measure, which is a normal state.

<Warning>
  Both writes are retroactive. Successes are recomputed on every read against
  the current definition, so editing a metric changes what past periods report
  and deleting one removes the numbers it reported for earlier conversations
  too. Nothing is pinned per period.
</Warning>

<Note>
  Over MCP, setting and deleting require a role that can edit initiatives
  (Owner, Admin or Member); listing and the catalog work for any role that can
  see initiatives. Over REST all four take a valid organization
  API key, and any valid key can make any of these calls: treat a key as full
  access to your organization and scope who holds it accordingly.
</Note>

An initiative is capped at ten ACTIVE metrics over this surface. Past that,
`POST` is refused until you retire one or pass its `rootId` to replace it.

## What you get

**Per node**, from the messages themselves with nothing to configure: sent,
delivered, read and replied counts, how each branch split, and median wait times.
Useful for finding the step where people fall out.

**A funnel** that starts at Sent rather than at enrolled, with each stage showing
its share of the previous stage and of the first, ending in a shared succeeded
stage.

**A success rate** whose denominator is the people Boom actually messaged, not
everyone who entered. Worth knowing before comparing it to a number from another
tool, which may well count differently.

**Successes over time**, bucketed by day, switchable between count and value when
the metric aggregates a value.

**The evidence behind the number**: the individual successes that matched, each
linking to that participant and to the run that produced it. This is the part
people ask for when they do not believe the dashboard.

<Warning>
  Metrics are recomputed on read against the current definition, and editing a
  definition creates a new version rather than pinning history. So changing what
  counts as success also changes what past periods show. Decide the definition
  before you need to defend a number with it.
</Warning>

## Reading the raw data instead

Everything the dashboard builds on is available over the API and MCP, covered in
[extraction](/extraction):

* the aggregate summary for an initiative, with coverage and distributions per field
* each participant's extracted values, including the quote the value came from and a confidence
* full transcripts, in batches, so you can pull every conversation without looping one at a time
* the step by step run timeline for a participant, when you need to know what the engine did rather than what was said

CSV and XLSX exports live in the app, including one row per participant with one
column per extracted field.

## What this is not

There is no experiment primitive: no randomized allocation, no significance
testing. You can compare variants by branching a journey on an attribute and
reading each path's success metric, which answers most questions, but the split
is deterministic and the statistics are yours to do.

There is no warehouse sync. Bulk reads are polling.

Outbound webhooks do exist for journey-run lifecycle events, and are the
exception to "reads are polling": Boom can POST to an endpoint you own when a
run starts, when a run ends (with the reason it ended), and when someone
matched a trigger but was not enrolled. They are enabled per organization, so
talk to us if you want them switched on.

## Related

<CardGroup cols={2}>
  <Card title="Extraction" icon="table" href="/extraction">
    The typed fields a conversation yields, and the read paths behind these numbers.
  </Card>

  <Card title="Journeys" icon="route" href="/journeys">
    The flow whose nodes these per step metrics describe.
  </Card>

  <Card title="Events" icon="bolt" href="/events">
    Record the events a success metric can watch for.
  </Card>

  <Card title="Initiatives" icon="rocket" href="/initiatives">
    The mission a success metric belongs to.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.