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

# Customer Value

> How Customer Value data points and rules adjust payout and revenue based on a customer's history.

Customer Value tracks what an individual customer has done over time and adjusts payout and revenue once that customer reaches a goal you define. Where a normal payout applies to a single conversion, a Customer Value rule looks at everything the customer has accumulated — conversions, events, sale amount, and your own custom attributes — and reacts when a threshold is crossed.

Customers are identified by the `user_id` you pass on conversions. Conversions without a `user_id` are not tracked by Customer Value.

There are two resources:

<CardGroup cols={2}>
  <Card title="Data points" icon="tag" href="/api-reference/get-networkscustomervaluedatapoints">
    Custom attributes you send with conversions — subscription tier, deposit
    amount, product SKU. Rules read them as goal metrics and as payout or
    revenue sources.
  </Card>

  <Card title="Rules" icon="sliders" href="/api-reference/get-networkscustomervaluerules">
    The goals a customer must reach, the window they must reach them in, and the
    payout or revenue outcome applied once they do.
  </Card>
</CardGroup>

## Data points

A data point declares an attribute you send with your conversions. The `identifier` is the key you send it under; it is lowercased on save and must be unique within the network.

The `type` is required and determines what you can do with it. A value other than `text` or `number` is rejected rather than defaulted, because the type cannot be changed afterwards and a text data point can never satisfy a numeric goal.

| Type     | Goal comparisons                                                                               | Usable as a payout or revenue source |
| -------- | ---------------------------------------------------------------------------------------------- | ------------------------------------ |
| `number` | `greater_than`, `less_than`, `equals`, reduced with `min` / `max` / `sum`                      | Yes                                  |
| `text`   | `begins_with`, `ends_with`, `contains`, `exact_match`, reduced with `all` / `some` / `current` | No                                   |

`identifier` and `type` are immutable once the data point exists, because rules and stored customer history reference them. Updates apply only `name`, `status`, and `description` — and omitting `status` leaves it as it is, so an `inactive` data point is not reactivated by a payload that simply does not mention it.

Only `active` data points can be referenced by a rule. Set a data point to `inactive` to retire it while keeping the history already collected — deletion is blocked while any rule still references it.

## Rules

A rule has five parts.

### Scope

Scope decides which traffic the rule applies to. Leave a list empty to match everything.

* `offer_ids` — the offers in scope. Mutually exclusive with `advertiser_ids`.
* `advertiser_ids` — every offer of these advertisers. Ignored when `offer_ids` is set.
* `affiliate_ids` — the partners in scope.
* `payout_revenue_id` — narrows the rule to a single event of the one offer in `offer_ids`. Leave it at `0` to cover the offer's base conversion and all of its events.

`segmentation` decides how the accumulated history is partitioned. `shared` keeps one history per customer across the whole scope. The other values (`affiliate`, `offer`, `advertiser`, `affiliate_offer`, `affiliate_advertiser`) keep a separate history per partner, per offer, per advertiser, or per combination — so the same customer progresses independently in each.

### Timeframe and cycles

`start_date` is inclusive, `end_date` is exclusive, and both are `yyyy-MM-dd` interpreted in `timezone_id` (the network's timezone by default). Leave `start_date` empty to start immediately and `end_date` empty to run indefinitely.

Every metric and every data point accumulates toward the rule's goals — conversions, events, payout, revenue, sale amount, and each data point the customer sends. `cycle_type` decides when those accumulated totals reset to zero:

| Cycle type                        | What happens                                                                                                          |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `day`, `week`, `month`, `quarter` | Totals reset on each calendar boundary, in the rule's timezone                                                        |
| `rule_duration`                   | No reset — the whole rule is a single cycle                                                                           |
| `from_first_conversion`           | No reset — instead the rule stops applying to a customer `cycle_duration` days after that customer's first conversion |

### Goals

`goals` are the conditions the customer's accumulated totals must satisfy. All goals must be satisfied for the outcome to apply. Each goal picks a `metric`, an `operator`, and a `value` — always sent as a string, even for numeric comparisons.

A `data_point` goal also needs `metric_data_point_identifier` and a `logic` that reduces the values collected over the cycle to a single one before comparison.

A rule may be goalless only when `cycle_type` is `from_first_conversion` and `outcome_type` is `substitution` — every customer in scope then gets the outcome for the length of their window.

### Progress settings

By default every accumulated total resets at the end of each cycle. `progress_settings` are the exceptions: each one names a single metric — or a single data point, via `data_point_identifier` — whose total carries over into the next cycle instead of resetting. Everything you don't list keeps resetting.

`condition` decides whether the carry-over applies at a given boundary:

* `any_value` — always carries over. The total never resets.
* `negative_balance` — carries over only when the total is negative at the boundary; a zero or positive total resets as usual. Use it so a customer whose refunds or chargebacks put them in the red starts the next cycle still in the red, rather than back at zero. Text data points have no balance and never carry over under this condition.

Each metric may appear at most once, and `data_points` once per data point.

Progress settings only take effect where a cycle boundary exists, so they are meaningful on `day`, `week`, `month`, and `quarter` cycles. A `rule_duration` or `from_first_conversion` cycle never resets, so there is nothing for them to override.

### Outcome

Goals are evaluated against the customer's accumulated totals, not against a single conversion. Each incoming conversion is added to the history first, then the goals are checked — so the conversion being processed when the history first satisfies them is the one the outcome lands on.

`outcome_type` decides what that outcome is:

* `substitution` replaces the payout and revenue of that incoming conversion.
* `bonus` records a separate bonus conversion and leaves the incoming one untouched. It needs an `outcome_trigger`: `instant` grants the bonus on the incoming conversion, `end_of_cycle` grants it once when the cycle closes, aggregating the whole cycle.

The amounts come from `payout_method` and `revenue_method`, which are configured independently. At least one of them must be enabled.

| Method       | How the amount is computed              | Fields used                                                      |
| ------------ | --------------------------------------- | ---------------------------------------------------------------- |
| `disabled`   | Left untouched                          | —                                                                |
| `modifier`   | Adjusts the original amount             | `*_modifier`, `*_value`                                          |
| `model`      | Computed from a payout or revenue model | `*_type`, `*_value`, `*_percentage`                              |
| `data_point` | Derived from a numeric data point       | `*_data_point_identifier`, `*_value`, `*_data_point_calculation` |

For `modifier`, `increase` and `decrease` treat the value as a percentage while `flat_increase` and `flat_decrease` treat it as an absolute amount. For `data_point`, `accumulated` uses the total across the cycle and `current` uses the value on the incoming conversion.

## Rule lifecycle

`state` is derived on read from the rule's timeframe and configuration — you never set it.

| State             | Meaning                                                                                                    |
| ----------------- | ---------------------------------------------------------------------------------------------------------- |
| `scheduled`       | The start date has not been reached yet                                                                    |
| `running`         | Active and applying                                                                                        |
| `stopped_running` | Within its timeframe, but its configuration is no longer valid to apply. `stopped_running_reason` says why |
| `expired`         | The end date has been reached                                                                              |

The state also controls what an update can change, so that a rule cannot be redefined out from under the history it has already accumulated:

| State                        | Fields an update applies                                                                                                                                                                                                                                   |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `scheduled`                  | Everything                                                                                                                                                                                                                                                 |
| `running`, `stopped_running` | `name`, `status`, `end_date`, the scope, the payout and revenue settings, and `outcome_payout_revenue_id`. `start_date`, `segmentation`, `timezone_id`, the cycle settings, `goals`, `outcome_type`, `outcome_trigger`, and `progress_settings` are locked |
| `expired`                    | `name` only                                                                                                                                                                                                                                                |

<Note>
  Updates replace the whole rule — send the complete object. Fields you omit are
  treated as cleared, not preserved.
</Note>

`status` is separate from `state`: an `inactive` rule never applies, whatever its state. Prefer setting `status` to `inactive` over deleting a rule you may want back.

## Configuration constraints

Some combinations are rejected on create and update:

| Constraint                                                                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------------- |
| At least one of `payout_method` and `revenue_method` must be enabled                                                                    |
| A `bonus` outcome requires at least one goal                                                                                            |
| A goalless rule requires `cycle_type` to be `from_first_conversion`                                                                     |
| A `bonus` outcome with `payout_method: model` requires `payout_type: cpa`; with `revenue_method: model` it requires `revenue_type: rpa` |
| An `end_of_cycle` trigger rejects `current` goal logic and `current` data point calculations                                            |
| An `end_of_cycle` trigger with `cycle_type: rule_duration` requires an `end_date`, since that cycle only ever closes there              |
| An `end_of_cycle` trigger requires `outcome_payout_revenue_id`                                                                          |
| A `payout_revenue_id` pointing at the base conversion rejects `event` goals; one pointing at an event rejects `conversion` goals        |
| A private event in `payout_revenue_id` rejects any payout setting — only revenue may be adjusted                                        |
| Every data point a rule references must exist and be `active`                                                                           |

A rule that becomes invalid after the fact — for example when its scoped event is made private — reports `stopped_running` rather than failing.

## Reading after a write

Reads are served from a replica, so a `GET` by ID issued immediately after a create can return `404` for a second or two before the new record is visible. The write itself has already succeeded; only the read lags.

If you are scripting against the API, use the object returned by the `POST` or `PUT` rather than re-fetching it — the response body is the saved record, including its assigned ID. Retry the read if you do need one.
