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

# Billable Metrics

Billable metrics tell Paygent *how to count* usage before applying your price. Without one, every API call counts as a single unit. With one, you bill on tokens, hours, unique documents, peak concurrency, or a custom formula.

## How billable metrics work

Three steps. You set up the meter once, link it to an agent indicator, then set your rate.

| Step                        | Where                            | Detail                                                                           | Example                                |
| --------------------------- | -------------------------------- | -------------------------------------------------------------------------------- | -------------------------------------- |
| **1. Create the meter**     | Billable Metrics → Create metric | Pick an aggregation (Sum, Unique count, Max…) and the metaTags property to read. | Sum on field hours → total GPU-hours   |
| **2. Link to an indicator** | Agents → Step 2 Indicators       | Click "Link billable metric" and select your meter for that event.               | inference indicator → gpu\_hours meter |
| **3. Set your price**       | Agents → Step 3 Pricing          | FLAT, VOLUME, GRADUATED, or CREDITS — applied to the metered total.              | \$0.50/hr or 0.01 credits per token    |

**Flow:** SDK sends meta\_tags → Metric aggregates → Pricing applied → **Customer billed**

## Without vs with a metric

| Without a metric                                                                       | With Sum on hours                                                        |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| 3 jobs = 3 units                                                                       | 3 jobs = 60.2 GPU-hours                                                  |
| A 10-minute job and a 48-hour job both count as one event. Revenue doesn't match cost. | Each job bills for actual compute. Fair for customers, accurate for you. |

## Set up in the dashboard

Follow these three steps. Code integration comes after the meter is configured.

### Step 1 — Create a billable metric

Sidebar → **Billable Metrics** → **Create metric**. Fill in basic info, pick your aggregation type, and optionally add rounding rules or filters.

| Field                | Description                                                        |
| -------------------- | ------------------------------------------------------------------ |
| **Name**             | Human-readable label shown in the dashboard and dropdowns.         |
| **Identifier**       | Unique key (e.g. `gpu_hours`). Auto-generated from name on create. |
| **Aggregation type** | How events combine — Sum, Count, Max, Unique count, or Latest.     |
| **Aggregate on**     | Unique field = one metaTags key. Custom expression = a formula.    |

### Step 2 — Link to an indicator

On **Agents → Step 2: Indicators**, click **Link billable metric** and select your meter. Leave as **None** to keep billing per raw event.

### Step 3 — Set pricing on the agent

**Step 3: Pricing** — your rate applies to the metered quantity, not event count.

Available pricing types:

* `FLAT` — \$X per unit
* `VOLUME` — tiered rates
* `GRADUATED` — progressive tiers
* `CREDITS` — debit wallet

---

## Send metaTags from the SDK

Billable metrics read properties from `meta_tags` on each usage event. For indicator-based / metered billing, use `send_indicator` — the same pattern as our revenue-only examples. Every Paygent usage function accepts meta tags.

**`revenue_only_indicator.py — send_indicator with meta_tags`**

```python title="revenue_only_indicator.py — send_indicator with meta_tags"
import os
import paygent_sdk

paygent_sdk.init(os.getenv("PAYGENT_API_KEY"))

agent_id = "agent-premium-123"
customer_id = "customer-corp-456"
indicator_name = "inference"

# meta_tags keys must match your billable metric field names
tags = {"hours": "2.5"}

paygent_sdk.send_indicator(
    agent_id=agent_id,
    customer_id=customer_id,
    indicator=indicator_name,
    meta_tags=tags,
)
```

### Python SDK functions that accept `meta_tags`

| Function                         | When to use                                                                                 |
| -------------------------------- | ------------------------------------------------------------------------------------------- |
| `send_indicator`                 | Revenue-only / metered indicators — no LLM token payload needed. Best for billable metrics. |
| `send_usage`                     | LLM usage with token counts. Pass meta\_tags= or set on RawUsageData.                       |
| `send_usage_video`               | Video generation usage + meta\_tags on VideoUsageData or parameter.                         |
| `send_external_cost`             | Third-party costs (telephony, etc.) + meta\_tags on ExternalCostData.                       |
| `initialize_voice_session`       | Session-level tags inherited by all STT/LLM/TTS events in the session.                      |
| `paygent_meta_tags (auto-patch)` | OpenAI / Anthropic / Gemini calls — pass `paygent_meta_tags={...}` on the provider request. |

> **Tip**
>
> **All values are strings.** Pass meta tag values as strings (e.g. `str(gpu_hours)` or `"2.5"`). Keys are case-sensitive and must match your metric field name exactly. See Event Meta Tags for limits and validation rules.

---

## Real examples for every aggregation type

Each example shows the dashboard config, sample events, the resulting billed quantity, and a `send_indicator` call with the matching `meta_tags`. Property keys must match your metaTags exactly — they are case-sensitive.

### Count — Count how many events match (optionally filtered)

**Real-world product:** Regional API gateway — bill only for requests routed to us-east-1, not every global call.

**Dashboard setup:**

* Aggregation: `Count`

* Filter: `region = us-east-1`

* Identifier: `us_east_requests`

* Events this month: 50 events worldwide, 12 with region=us-east-1

* **Billed quantity: 12 units billed (only matching events)**

**`Python SDK — send_indicator`**

```python title="Python SDK — send_indicator"
import paygent_sdk

paygent_sdk.init(api_key="your-paygent-api-key")

paygent_sdk.send_indicator(
    agent_id="api-gateway",
    customer_id=customer_id,
    indicator="api-request",
    meta_tags={"region": "us-east-1", "path": "/v1/chat"},
)
```

### Sum — Add up a numeric property from every event

**Real-world product:** GPU inference platform — jobs range from 0.2 to 48 GPU-hours. Bill on actual compute, not call count.

**Dashboard setup:**

* Aggregation: `Sum`

* Aggregate on: `Unique field → hours`

* Identifier: `gpu_hours`

* Events this month: Job A: 0.2 hrs · Job B: 12 hrs · Job C: 48 hrs

* **Billed quantity: 60.2 GPU-hours billed**

**`Python SDK — send_indicator`**

```python title="Python SDK — send_indicator"
import paygent_sdk

paygent_sdk.init(api_key="your-paygent-api-key")

paygent_sdk.send_indicator(
    agent_id="gpu-agent",
    customer_id=customer_id,
    indicator="inference",
    meta_tags={"hours": str(gpu_hours)},
)
```

### Max — Bill on the highest value seen in the billing period

**Real-world product:** Realtime collaboration tool — charge based on peak concurrent users, not every heartbeat event.

**Dashboard setup:**

* Aggregation: `Max`

* Field: `concurrent_users`

* Identifier: `peak_concurrent_users`

* Events this month: Mon: 45 users · Wed: 120 users · Fri: 88 users

* **Billed quantity: 120 units billed (peak for the period)**

**`Python SDK — send_indicator`**

```python title="Python SDK — send_indicator"
import paygent_sdk

paygent_sdk.init(api_key="your-paygent-api-key")

paygent_sdk.send_indicator(
    agent_id="collab-agent",
    customer_id=customer_id,
    indicator="presence-ping",
    meta_tags={"concurrent_users": str(active_count)},
)
```

### Unique count — Count how many distinct values appear for a property

**Real-world product:** Document intelligence SaaS — charge per unique document analyzed, even if the same doc is re-processed multiple times.

**Dashboard setup:**

* Aggregation: `Unique count`

* Aggregate on: `Unique field → document_id`

* Identifier: `documents_processed`

* Events this month: doc-101 processed 3× · doc-202 processed 1× · doc-303 processed 2×

* **Billed quantity: 3 unique documents billed (not 6 events)**

**`Python SDK — send_indicator`**

```python title="Python SDK — send_indicator"
import paygent_sdk

paygent_sdk.init(api_key="your-paygent-api-key")

paygent_sdk.send_indicator(
    agent_id="doc-agent",
    customer_id=customer_id,
    indicator="analyze",
    meta_tags={"document_id": "doc-101", "pages": "24"},
)

# Same document_id sent again → still 1 unique doc for the period
```

### Latest — Use the most recent value received in the period

**Real-world product:** Seat-based AI workspace — customer adds and removes seats throughout the month. Bill on the latest seat count snapshot.

**Dashboard setup:**

* Aggregation: `Latest`

* Field: `seat_count`

* Identifier: `active_seats`

* Events this month: Week 1: 10 seats · Week 3: 25 seats · Week 4: 22 seats

* **Billed quantity: 22 units billed (latest value)**

**`Python SDK — send_indicator`**

```python title="Python SDK — send_indicator"
import paygent_sdk

paygent_sdk.init(api_key="your-paygent-api-key")

paygent_sdk.send_indicator(
    agent_id="workspace-agent",
    customer_id=customer_id,
    indicator="seat-sync",
    meta_tags={"seat_count": str(current_seats)},
)
```

### Custom expression — Compute a value with a formula before summing

**Real-world product:** Distributed inference cluster — bill on effective tokens (tokens × replica count), not raw tokens alone.

**Dashboard setup:**

* Aggregation: `Sum`

* Aggregate on: `Custom expression`

* Expression: `event.properties.tokens * event.properties.replicas`

* Result field: `calculation_result`

* Identifier: `effective_tokens`

* Events this month: Run 1: 1,000 tokens × 4 replicas · Run 2: 500 tokens × 2 replicas

* **Billed quantity: 5,000 units billed (4000 + 1000)**

**`Python SDK — send_indicator`**

```python title="Python SDK — send_indicator"
import paygent_sdk

paygent_sdk.init(api_key="your-paygent-api-key")

paygent_sdk.send_indicator(
    agent_id="cluster-agent",
    customer_id=customer_id,
    indicator="inference",
    meta_tags={"tokens": "1000", "replicas": "4"},
)

# Custom expression evaluates: 1000 * 4 = 4000 per event
```

---

> **Tip**
>
> **Unique field vs Unique count — don't confuse them:**
>
> * **Unique field** (under Aggregate on) — *how* you specify the input: a single metaTags key, or a custom expression.
> * **Unique count** (aggregation type) — *how* events combine: count distinct values of that field across the billing period.

> **Warning**
>
> **Linked metrics are protected.** Once attached to an agent indicator, aggregation and field settings lock to protect live billing. Create a new metric and re-link if you need different counting rules.