Concepts

Meters

Meters aggregate usage data from your API. They watch for specific event types, extract numeric values, and sum them over configurable time windows.

How Meters Work

A meter is configured with:

  • Event type - Which events to process (e.g., requests, tokens)
  • Value property - JSONPath to extract the numeric value from event data. Events use $.total as the standard value property.
  • Aggregation - How to combine values (typically SUM)

When events are ingested, the meter matches events by type, extracts the specified value, and aggregates it per customer subscription over time.

Common Examples

API Request Counting

Track the total number of API requests:

JSONCode
{ "slug": "api_requests", "name": "API Requests", "eventType": "api_requests", "aggregation": "SUM", "valueProperty": "$.total" }

Each event identifies the subscription being metered, the actor that drove the consumption, and how much to record. The subscription field carries the subscription ID, the subject field identifies the actor, and data.total carries the quantity:

JSONCode
{ "id": "5c10fade-1c9e-4d6c-8275-c52c36731d3c", "specversion": "1.0", "type": "api_requests", "source": "monetization-policy", "subject": "acme-prod", "subscription": "01KNVXHQG356VA7T7W0V9N21GH", "data": { "total": 1 } }

subject identifies who consumed the subscription's entitlements on this request — typically the API key's consumer name, the end-user id, or another stable per-actor identifier. It is not the subscription id (use the subscription field for that) and does not route billing. Its purpose is to let you break down usage within a subscription so you can see which key, user, or agent drove the consumption — a single subscription will commonly emit events with many different subject values. See Monetization Policy for how usage is recorded.

Token Usage

Track token consumption for AI applications:

JSONCode
{ "slug": "tokens", "name": "Token Usage", "eventType": "tokens", "aggregation": "SUM", "valueProperty": "$.total" }

The meter aggregates events from the gateway; the per-request quantity comes from the MonetizationInboundPolicy. Set a fixed cost per request in the policy's meters option, or call MonetizationInboundPolicy.setMeters from a custom outbound policy to report a value derived from the response — for example, the actual token count an LLM returned. An event for a request that consumed 50 tokens looks like this:

JSONCode
{ "id": "a1b2c3d4-5678-4abc-8def-1234567890ab", "specversion": "1.0", "type": "tokens", "source": "monetization-policy", "subject": "acme-prod", "subscription": "01KNVXHQG356VA7T7W0V9N21GH", "data": { "total": 50 } }

Data Transfer

Track bytes transferred:

JSONCode
{ "slug": "data_transfer", "name": "Data Transfer (bytes)", "eventType": "data_transfer", "aggregation": "SUM", "valueProperty": "$.total" }

Each event reports the number of bytes transferred:

JSONCode
{ "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "specversion": "1.0", "type": "data_transfer", "source": "monetization-policy", "subject": "acme-prod", "subscription": "01KNVXHQG356VA7T7W0V9N21GH", "data": { "total": 4096 } }

Naming Consistency

The meter eventType must match the key used in three places:

  1. The meter's slug and eventType
  2. The key in the monetization policy's meters configuration
  3. The featureKey on the plan's entitlement

If these don't match, usage is not tracked correctly against the subscription's entitlements.

Creating a Meter

TerminalCode
curl \ https://dev.zuplo.com/v3/metering/$BUCKET_ID/meters \ --request POST \ --header "Authorization: Bearer $ZAPI_KEY" \ --header "Content-Type: application/json" \ --data @- << EOF { "slug": "api_requests", "name": "API Requests", "eventType": "api_requests", "aggregation": "SUM", "valueProperty": "$.total" } EOF

API Reference

For complete API operations (list, get, update, delete), see the Meters API Reference.

Last modified on