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

# Pick a multi-touch attribution model

> Choose between first-touch, last-touch, linear, time-decay, and custom U-shaped credit when you run the multi-touch attribution report — what each model weights, how to run it from the dashboard or API, and how to read the channel and campaign rollups.

# Pick a multi-touch attribution model

A converting contact usually crosses several channels before the conversion — an email nurture, an SMS offer, a push reminder. The multi-touch attribution report answers **how credit for a conversion is split across the touchpoints that preceded it**, so you can compare channels and campaigns on the same footing instead of exporting your CDP event stream into an external tool. This guide covers choosing a model, running the report from the dashboard or the API, and reading the two rollups (by channel, by campaign).

For full request/response schemas, see the [CDP analytics API reference](/api-reference/cdp).

## The report surface

In the dashboard, open **Insights → Attribution**. Pick a conversion event (for example `purchased`, `booked_demo`, or `subscribed`), a lookback window, and an attribution model, then run the report. The pipeline joins every conversion in the (optional) time window to the touchpoints recorded within its lookback, then allocates exactly one conversion-credit across those touchpoints under your chosen model and rolls it up per channel and per campaign.

Every model normalises so each conversion contributes exactly 1.0 of credit — the channel and campaign rollups always reconcile to the conversion count, so switching models re-weights answer, never the sample.

## The models

| Model         | How it credits                                                                                                                                                                                                  | Pick it when                                                                                                                   |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `first_touch` | 100% to the earliest touchpoint in the window.                                                                                                                                                                  | You want to surface which channel or campaign introduced the customer (awareness).                                             |
| `last_touch`  | 100% to the latest touchpoint.                                                                                                                                                                                  | You want the closing channel — the one that actually drove the conversion.                                                     |
| `linear`      | Equal split across every touchpoint in the window.                                                                                                                                                              | You want a fairness-first view and dislike over-crediting a single touch.                                                      |
| `time_decay`  | A touch `t` before the conversion gets weight `2^(-t / half_life)` (default `half_life_days: 7`), normalised. Recent touches earn more.                                                                         | You believe influence concentrates near the conversion but do not want to discard the introduction entirely.                   |
| `custom`      | Position-based (U-shaped family): `first`/`last` weights go to the first and last touchpoints; the `middle` pool splits equally across the interior touches. Weights are normalised, so they need not sum to 1. | You want a hybrid that credits the opener and the closer and spread the middle, e.g. `{ first: 0.4, middle: 0.2, last: 0.4 }`. |

Choose the model that matches how you think about influence — the underlying set of conversions does not change; only the credit split re-weights.

## Running it over the API

`POST /api/v1/cdp/analytics/attribution`. Only owner / admin / developer keys with the `contacts:read` scope can run it (it reads the PII-adjacent event stream).

```bash theme={null}
curl -X POST "https://api.orbit.devotel.io/api/v1/cdp/analytics/attribution" \
  -H "X-API-Key: $ORBIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "time_decay",
    "conversion_event": "purchased",
    "lookback_days": 30,
    "half_life_days": 7
  }'
```

Useful knobs:

| Field                                    | Meaning                                                                                                                            |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `lookback_days` (1–365, default 30)      | How far before each conversion to gather touchpoints.                                                                              |
| `half_life_days` (0.1–365, default 7)    | Only for `time_decay` — a touch this many days before the conversion gets 50% credit.                                              |
| `custom_weights`                         | Only for `custom` — `{ first, middle, last }` numbers (normalised internally).                                                     |
| `since` / `until`                        | Optional ISO bounds on the conversion window.                                                                                      |
| `channel_property` / `campaign_property` | Event properties the rollup uses to label channels and campaigns (defaults to the conventional `channel` / `campaign` properties). |
| `touchpoint_events`                      | Optionally restrict which event types count as touchpoints.                                                                        |

## Reading the report

The response returns `credit_by_channel[]` and `credit_by_campaign[]`, each row carrying `credit`, `conversions`, and `credit_share` (the fraction of total credit), so a channel-level view and a campaign-level view come back in one round-trip. `attributed_conversions` and `unattributed_conversions` tell you how many conversions had no touchpoint inside their lookback (those still count toward `total_conversions`).

If a very touch-heavy window exceeds the read cap, the response flags `touch_rows_capped: true` and the report becomes a lower bound — re-run with a tighter window or narrower `touchpoint_events` to raise the ceiling.

## Choosing a window and model together

A short `lookback_days` with `last_touch` is the standard "closer" report. A long `lookback_days` with `first_touch` or `linear` surfaces awareness. `time_decay` pairs well with a long lookback because it still rewards the earliest touches while skewing toward the close. If you are comparing channels on a level field, prefer `linear`; if you are deciding where to add budget, `last_touch` under-credits upper-funnel channels — read both so you do not defund your introductions.
