> This page is for version v2 (default).
> For other versions, use one of these documentation indexes:
> - v2 (default): https://docs.paid.ai/v-2/llms.txt
> - v1: https://docs.paid.ai/v-1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.paid.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.paid.ai/_mcp/server.

# Delivered value

> Track the measurable value your AI agent delivers to customers alongside billing

## What is delivered value?

Delivered value lets you quantify and display the real-world impact your AI agent has for each customer: hours saved, meetings booked, emails written. Where billing signals tell Paid *what to invoice*, delivered value tells your customers *what they got for the money*.

The calculated results appear on value receipts and in the customer portal, giving customers a concrete return-on-investment figure alongside their bill.

You define delivered value on the [**Delivered value**](https://app.paid.ai/configure/value-studio) page (**Value** → **Metrics** in the sidebar). Each value metric, for example *Hours saved*, reads one signal, calculates a value from it, and can convert that value into currency. Your organization's value metrics together make up its value model. A new organization starts with no value metrics, so nothing is calculated until you create one.

## Prerequisites

* A [Paid API key](https://app.paid.ai/settings/api-keys) and the Paid SDK installed wherever you send signals.
* Delivered value turned on for your organization. If **Metrics** doesn't appear under **Value** in the sidebar, contact Paid support to turn it on.
* [Signals](/documentation/getting-started/first-signals) flowing with the customer, product, and `data` fields your value calculation will use.

## Step 1: Create a value metric

Open [**Value** → **Metrics**](https://app.paid.ai/configure/value-studio) and click **Create value metric**. Then fill in:

* **Signal**: the event this metric reads. The list shows event names your organization has sent, events that usage pricing on an active product charges for, and events your meters emit.
* **Metric name**, plus the external short and long descriptions customers see on value receipts.
* **Value type**: the kind of value, one of *Human value equivalent*, *Time saved*, *Cost savings*, *Revenue generated*, or *Risk avoided*. It decides which units you can pick.
* **Unit of measurement**: how the metric is counted. *Cost savings* and *Revenue generated* are always measured in currency.
* **Monetary conversion** (optional): turn on **Also show this value metric in a currency** to convert the result at a flat rate or across graduated bands, for example an hourly rate for a time-based metric.
* **Variables** and **Value formula**: how the value is calculated from the signal. See [Variables](#variables).

Check the **Preview**, then click **Create value metric** and confirm. Paid adds the metric to your value model and publishes it, and every new signal for that event has delivered value calculated from then on. Signals sent before you published are not recalculated until you [run a backfill](#backfilling-historical-signals).

To change a metric later, open it from the list. You can edit its details, its variable values, its monetary conversion rate and its signal's label. You can't change its signal or formula; create a new metric instead. Each saved change publishes a new version of the value model.

> Tip: Several value metrics can read the same signal. For example, you might track both *Hours saved* and *Cost saved* from one event.

## Step 2: Send signal data that feeds the calculation

If every variable in a metric is **Fixed** (for example, a fixed hourly rate and a fixed number of minutes saved per action), no extra signal data is needed and delivered value is calculated for every signal.

If your calculation depends on per-signal data, pass those values in the `data` field:

#### Python

```python
from paid import Paid, Signal, CustomerByExternalId, ProductByExternalId

paid_client = Paid(token="YOUR_PAID_API_KEY")

paid_client.signals.create_signals(
    signals=[
        Signal(
            event_name="document_processed",
            customer=CustomerByExternalId(
                external_customer_id="<your_external_customer_id>",
            ),
            attribution=ProductByExternalId(
                external_product_id="<your_external_product_id>",
            ),
            data={
                # business data - also used by delivered value calculations
                "document_id": "doc_abc123",
                "time_saved": 45,
                "time_saved_unit": "minutes",  # seconds | minutes | hours | days
                "page_count": 12,
            },
        )
    ],
)
```

#### Node.js

```typescript
import { PaidClient } from "@paid-ai/paid-node";

const paidClient = new PaidClient({ token: "YOUR_PAID_API_KEY" });

await paidClient.signals.createSignals({
  signals: [
    {
      eventName: "document_processed",
      customer: {
        externalCustomerId: "<your_external_customer_id>",
      },
      attribution: {
        externalProductId: "<your_external_product_id>",
      },
      data: {
        // business data - also used by delivered value calculations
        document_id: "doc_abc123",
        time_saved: 45,
        time_saved_unit: "minutes",  // "seconds" | "minutes" | "hours" | "days"
        page_count: 12,
      },
    },
  ],
});
```

#### Go

```go
import (
    paid "github.com/paid-ai/paid-go"
    paidclient "github.com/paid-ai/paid-go/client"
    "github.com/paid-ai/paid-go/option"
)

paidClient := paidclient.NewClient(option.WithToken("YOUR_PAID_API_KEY"))

_, err := paidClient.Signals.CreateSignals(ctx, &paid.BulkSignalsRequest{
    Signals: []*paid.Signal{
        {
            EventName: "document_processed",
            Customer: &paid.CustomerAttribution{
                CustomerByExternalID: &paid.CustomerByExternalID{
                    ExternalCustomerID: "<your_external_customer_id>",
                },
            },
            Attribution: &paid.Attribution{
                ProductByExternalID: &paid.ProductByExternalID{
                    ExternalProductID: "<your_external_product_id>",
                },
            },
            Data: map[string]interface{}{
                // business data - also used by delivered value calculations
                "document_id":     "doc_abc123",
                "time_saved":      45,
                "time_saved_unit": "minutes", // "seconds" | "minutes" | "hours" | "days"
                "page_count":      12,
            },
        },
    },
})
if err != nil {
    return err
}
```

This example sends `time_saved_unit`, which Paid reads only when the metric's **Signal sends this in** setting is **A field on the signal (`time_saved_unit`)**. See [Duration values](#duration-values).

The field names in `data` must match what your value metric reads. Open the metric on the [Delivered value](https://app.paid.ai/configure/value-studio) page to see them: its **Calculation** card lists the fields it reads under **Signal-bound values**, or **Per-segment values** for a per-segment variable.

### Variables

Each variable in a value metric gets its value in one of four ways:

* **Fixed**: the same number for every signal, such as an hourly rate.
* **Per signal**: read from a field in the signal's `data`, such as `data.time_saved`. The **Fallback default** is used when the field is missing.
* **Graduated**: picked from banded ranges by a number in the signal's `data`. A metric can have one graduated variable.
* **Per segment**: picked from a table by the value of one field in the signal's `data`, such as a plan tier, with a default when no row matches. A metric can have one per-segment variable.

### Duration values

For a *Time saved* metric, a **Per signal** variable has a **Signal sends this in** setting. The default, **Same as metric (no conversion)**, reads the number in the metric's unit. Pick a unit (**Seconds**, **Minutes**, **Hours** or **Days**) if every signal reports in that unit. Pick **A field on the signal (`time_saved_unit`)** to have each signal name its unit in a companion `<field>_unit` field, accepting `"seconds"`, `"minutes"`, `"hours"`, or `"days"`. Paid converts the value into the metric's unit. If the companion field is missing or holds another value, Paid uses the **Fallback default**, which you enter in the metric's unit and which is not converted.

### Monetary values

Monetary values represent real currency amounts, for example the deal value closed by an AI SDR. Send money amounts in the main unit of your value model's currency, as a plain number (for example `5` or `5.25` for \$5.25). Paid uses the number as sent and shows it as a currency amount on the dashboard and value receipts.

## Step 3: View delivered value in the dashboard

After signals start flowing, delivered value appears in several places:

* [**Analytics** → **Delivered value**](https://app.paid.ai/?tab=value): org-wide delivered value over time, broken down by value type and customer, with revenue and ROI comparisons
* **Signals analytics**: per-event aggregate delivered value shown inline in the events table
* **Signal detail**: the calculated delivered value for an individual signal, visible when opening a signal row
* **Customer portal**: customers see their delivered value KPIs, trend chart, and a breakdown by value type and signal via their portal link
* **Customer detail**: the value receipts tab on each customer's page lists their receipts with delivered value summaries

Use [**Invoice** → **Value receipts** → **Configure templates**](https://app.paid.ai/invoice/value-receipts/configure) to configure which signals and data fields appear on customer-facing receipts.

## Backfilling historical signals

Publishing a change to your value model applies to new signals only. Signals already ingested keep the delivered value they were given when they arrived (none, if no metric covered them yet) until you run a backfill. While history is behind, the [Delivered value](https://app.paid.ai/configure/value-studio) page and each metric's page show a **Latest changes aren't applied to history yet** banner. Click **Run backfill** there to recalculate delivered value for all your existing signals against the current value model. While it runs, the banner reads **Applying the latest changes to history**, and it clears when the backfill finishes. To start a backfill from code, call [`POST /api/v2/value-models/backfill`](/api-reference/api-reference/value-models/refresh-value-model-backfill).

A backfill recalculates every signal the current value model covers; there is no per-signal or start-date option. If a backfill fails, the banner reads **The last backfill failed**, shows the error, and offers **Run backfill** to retry. Existing billing data is never changed, only the delivered value records. Re-running is safe: the system versions every result and always uses the latest, so running the backfill twice produces the same totals as running it once.

## Currency

A value model has one currency, your organization's default currency when it was created. Monetary conversions and currency-measured metrics produce amounts in that currency. Paid never applies exchange rates.