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.

StepWhereDetailExample
1. Create the meterBillable Metrics → Create metricPick an aggregation (Sum, Unique count, Max…) and the metaTags property to read.Sum on field hours → total GPU-hours
2. Link to an indicatorAgents → Step 2 IndicatorsClick “Link billable metric” and select your meter for that event.inference indicator → gpu_hours meter
3. Set your priceAgents → Step 3 PricingFLAT, 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 metricWith Sum on hours
3 jobs = 3 units3 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 MetricsCreate metric. Fill in basic info, pick your aggregation type, and optionally add rounding rules or filters.

FieldDescription
NameHuman-readable label shown in the dashboard and dropdowns.
IdentifierUnique key (e.g. gpu_hours). Auto-generated from name on create.
Aggregation typeHow events combine — Sum, Count, Max, Unique count, or Latest.
Aggregate onUnique field = one metaTags key. Custom expression = a formula.

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
1import os
2import paygent_sdk
3
4paygent_sdk.init(os.getenv("PAYGENT_API_KEY"))
5
6agent_id = "agent-premium-123"
7customer_id = "customer-corp-456"
8indicator_name = "inference"
9
10# meta_tags keys must match your billable metric field names
11tags = {"hours": "2.5"}
12
13paygent_sdk.send_indicator(
14 agent_id=agent_id,
15 customer_id=customer_id,
16 indicator=indicator_name,
17 meta_tags=tags,
18)

Python SDK functions that accept meta_tags

FunctionWhen to use
send_indicatorRevenue-only / metered indicators — no LLM token payload needed. Best for billable metrics.
send_usageLLM usage with token counts. Pass meta_tags= or set on RawUsageData.
send_usage_videoVideo generation usage + meta_tags on VideoUsageData or parameter.
send_external_costThird-party costs (telephony, etc.) + meta_tags on ExternalCostData.
initialize_voice_sessionSession-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.

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
1import paygent_sdk
2
3paygent_sdk.init(api_key="your-paygent-api-key")
4
5paygent_sdk.send_indicator(
6 agent_id="api-gateway",
7 customer_id=customer_id,
8 indicator="api-request",
9 meta_tags={"region": "us-east-1", "path": "/v1/chat"},
10)

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
1import paygent_sdk
2
3paygent_sdk.init(api_key="your-paygent-api-key")
4
5paygent_sdk.send_indicator(
6 agent_id="gpu-agent",
7 customer_id=customer_id,
8 indicator="inference",
9 meta_tags={"hours": str(gpu_hours)},
10)

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
1import paygent_sdk
2
3paygent_sdk.init(api_key="your-paygent-api-key")
4
5paygent_sdk.send_indicator(
6 agent_id="collab-agent",
7 customer_id=customer_id,
8 indicator="presence-ping",
9 meta_tags={"concurrent_users": str(active_count)},
10)

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
1import paygent_sdk
2
3paygent_sdk.init(api_key="your-paygent-api-key")
4
5paygent_sdk.send_indicator(
6 agent_id="doc-agent",
7 customer_id=customer_id,
8 indicator="analyze",
9 meta_tags={"document_id": "doc-101", "pages": "24"},
10)
11
12# 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
1import paygent_sdk
2
3paygent_sdk.init(api_key="your-paygent-api-key")
4
5paygent_sdk.send_indicator(
6 agent_id="workspace-agent",
7 customer_id=customer_id,
8 indicator="seat-sync",
9 meta_tags={"seat_count": str(current_seats)},
10)

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
1import paygent_sdk
2
3paygent_sdk.init(api_key="your-paygent-api-key")
4
5paygent_sdk.send_indicator(
6 agent_id="cluster-agent",
7 customer_id=customer_id,
8 indicator="inference",
9 meta_tags={"tokens": "1000", "replicas": "4"},
10)
11
12# Custom expression evaluates: 1000 * 4 = 4000 per event

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.

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.