Usage Events
A usage event is the smallest unit of usage Meterry accepts. Your backend or gateway sends a JSON envelope to the ingest API; Meterry stores it as a raw event, applies the published extractor rule set, builds normalized usage events, expands charge items, and rates them when pricing is available.
This page is a field-by-field tour of the event envelope. For the full request and response schema, see the Ingest Usage Event and Batch Ingest Usage Events API pages.
Ingest event envelope
Section titled “Ingest event envelope”A single ingest call carries one envelope. The shape below shows every supported top-level field; you only send the fields your workflow needs.
{ "source": "openai-gateway", "external_event_id": "chatcmpl_123", "idempotency_key": "openai-gateway:chatcmpl_123", "subject_type": "organization", "subject_id": "org_001", "occurred_at": 1781222400, "raw_json": { "type": "response", "provider": "openai", "usage": { "model": "gpt-4.1-mini", "prompt_tokens": 1200, "output_tokens": 300 }, "meta": { "org_id": "org_001", "user_id": "user_123", "api_key_id": "key_001" } }, "x-billing": { "items": [ { "metric": "tool_call.web_search", "quantity": 1, "unit": "call" } ], "pricing_hints": { "tool_call.web_search": { "unit_price": 0.1, "pricing_unit": 1, "currency": "USD" } } }, "x-usage-control": { "budget_lease_id": "ble_..." }, "metadata": { "gateway_region": "us-east-1" }}| Field | Required | Purpose |
|---|---|---|
source |
Yes | Stable event-source name, for example openai-gateway, agent-runtime, or workflow-engine. Use it to group events by producer in analytics and to filter for support. |
external_event_id |
No | The upstream event or request ID. Carries through to the processed usage event so support and reconciliation can join Meterry data back to your system. |
idempotency_key |
Strongly recommended | A stable retry key. Reusing the same key in the same tenant produces the same raw_event_id; processing then deduplicates and never writes the raw event fact twice. Use the upstream request ID when one exists. |
subject_type |
Conditionally | Explicit subject type for this event. Must match [a-z][a-z0-9_]{0,63} and must be supplied together with subject_id. |
subject_id |
Conditionally | Explicit subject ID for this event. Must be supplied together with subject_type. |
occurred_at |
No | Event occurrence time as Unix seconds. Defaults to the server receive time. Use this to keep backfills and out-of-order deliveries routed to the correct window. |
raw_json |
Yes | The original usage JSON. Its shape is yours to design; the extractor rule set decides which fields become subject, dimensions, and charge items. |
x-billing |
No | Dynamic billing extension. Use it for sparse request-level items, pricing hints, and discount hints. See Dynamic Billing below. |
x-usage-control |
No | Usage-control extension. Set budget_lease_id to count this event against a one-time Budget Lease. See Budget Lease integration below. |
metadata |
No | Ingest-side metadata for audit and operations. Keep it small and non-sensitive. Categorical values automatically become dimensions on the rated usage event (a value that is pure digits is treated as an identifier and is skipped). |
source, external_event_id, and idempotency_key are the trio that makes the event traceable and replayable. subject_type / subject_id, occurred_at, and raw_json are the trio that drives normalization and rating. The x-* extensions and metadata add request-level context without changing the underlying extractors.
Subject resolution
Section titled “Subject resolution”The subject is the entity that produced the usage. It determines which billing account owns the event and which usage-control limits apply. Meterry resolves it in this order:
- Explicit subject on the envelope. When both
subject_typeandsubject_idare present at the top level, Meterry uses that pair and does not run the extractor’s subject paths. Supplying only one of the two is invalid. - Path-based subject in the extractor. Otherwise Meterry runs the precompiled
subject.type_pathandsubject.id_pathaccessors againstraw_json. Each path value wins over its matchingdefault_typeordefault_id. - Required check. If the rule set marks the subject as
requiredand the result is still incomplete, normalization fails and the event is recorded as unconsumed. If it is optional, an incomplete subject pair is discarded and the event continues without a billing owner.
A dynamic subject type that comes from a path or default must still match [a-z][a-z0-9_]{0,63}. A wrong JSON type or an invalid subject type is rejected rather than silently substituted by a default.
Inside raw_json
Section titled “Inside raw_json”raw_json is your own JSON. Meterry does not require any specific shape; the extractor rule set tells the runtime which fields to read.
A typical LLM event looks like:
{ "type": "response", "provider": "openai", "usage": { "model": "gpt-4.1-mini", "prompt_tokens": 1200, "output_tokens": 300 }, "meta": { "user_id": "u_01" }}The rule set then maps that shape onto the normalized model:
meta.user_idbecomes thesubject_id, with the rule’sdefault_typefilling insubject_type.providerandusage.modelbecome dimensions you can group by in analytics.usage.prompt_tokensandusage.output_tokensbecome stable charge items with attached pricing.
The subject block, dimensions block, and charge_item_extractors block in the rule set are how you tell Meterry where to read each piece. See Create Rules and the LLM Gateway use case for end-to-end examples.
Dynamic Billing
Section titled “Dynamic Billing”x-billing sits next to metadata at the top level of the request body. It carries three optional maps:
items— sparse request-level charge items that the extractor cannot know about, such as optional tool calls or one-off add-ons.pricing_hints— per-metric overrides for unit price, pricing unit, and currency. Useful when the gateway picks the price dynamically.discount_hints— per-metric discount adjustments layered on top of the rated price.
When the same metric is produced by both the extractor and x-billing.items, the reported x-billing item wins for that metric. See the full contract on the Ingest Usage Event API page and learn the runtime order in How Extraction Runs.
Budget Lease integration
Section titled “Budget Lease integration”For agent runs that need a one-time hard cap, set x-usage-control.budget_lease_id on the envelope. Meterry:
- Snapshots the lease ID on the normalized usage event for audit.
- Debits the underlying billing account normally.
- Accumulates the rated amount against the lease window atomically.
- Emits
budget_lease.exhaustedonly when a new rated version pushes the lease at or above its cap.
Replays of the same rated version are deduplicated, so retries do not double-charge the lease. See Create Budget Lease for the full request contract.
Send events from a trusted backend
Section titled “Send events from a trusted backend”Use a project API key from API keys.
Authorization: Bearer <secret>Content-Type: application/jsonDo not send ingestion secrets from browser code. The ingest API is intended for trusted backends, gateways, and server-side SDKs.
Processed usage event
Section titled “Processed usage event”After ingestion, Meterry returns a normalized usage event. Listing endpoints surface that normalized shape, with one row per event:
{ "tenant_id": "t_001", "project_id": "proj_gateway", "event_date": "2026-06-12", "occurred_at": 1781222400, "usage_event_id": "usage_evt_01", "raw_event_id": "raw_evt_01", "source": "llm_gateway", "external_event_id": "chatcmpl_123", "subject_type": "user", "subject_id": "user_123", "billing_account_id": "acct_xxx", "labels": { "provider": "openai", "model": "gpt-4.1-mini" }, "metrics": { "input_tokens": { "value": "1200", "unit": "token", "currency": "USD", "amount": "0.00024", "unit_price": "0.0000002" }, "output_tokens": { "value": "300", "unit": "token", "currency": "USD", "amount": "0.00024", "unit_price": "0.0000008" } }, "usage_version": 42, "created_at": 1781222400}| Field | Purpose |
|---|---|
usage_event_id |
Stable ID for the normalized usage event. Use this to join against downstream charge item rows. |
raw_event_id |
Stable ID for the underlying raw event. It is also the idempotency_key you passed in, so you can trace a processed event back to your original request. |
subject_type / subject_id |
The resolved subject after the explicit / path / default resolution above. |
billing_account_id |
The account that owns this usage for fund debit. It is the persisted subject-route snapshot, not a label you can override. |
event_date |
The event’s calendar date in the project’s reporting timezone, derived from occurred_at. Use it for daily aggregation. |
occurred_at |
The event occurrence time in Unix seconds. This is the same value you sent on the envelope (or the server receive time when omitted). |
source |
The ingest source name you provided. |
external_event_id |
The upstream ID you provided, echoed back so you can join to your system. |
labels |
The resolved dimensions for the event, keyed by dimension name. |
metrics |
A flat map keyed by metric. Each entry carries the rated value, unit, currency, amount, and unit_price. Nested physical paths are surfaced as dotted logical metric names such as tool_call.web_search. |
usage_version |
Monotonic version assigned to the event after rating. Use it to deduplicate replays when comparing two readings of the same event. |
created_at |
When Meterry finished processing the event. |
For the full query contract and filter parameters, see List Usage Events. When you also need the per-charge-item breakdown, use List Usage Event Details with the usage_event_id.
Inspect results
Section titled “Inspect results”Open Usage explorer.
- Choose a time window.
- Add label filters such as
provider=openai; model=gpt_4o_miniwhen needed. - Choose breakdown dimensions such as metric, model, or provider.
- Select Show usage.
Use Live to refresh recent activity every few seconds. Advanced filters support subject type, subject ID, metrics, breakdown dimensions, and row limits.
Related pages
Section titled “Related pages”- Ingest Usage Event — single-event request and response schema.
- Batch Ingest Usage Events — multi-event request that lets each item target its own extractor rule set.
- List Usage Events — query contract for processed usage events.
- List Usage Event Details — per-event charge item rows.
- Create Rules — how the extractor turns
raw_jsoninto subject, dimensions, and charge items. - How Extraction Runs — runtime order, the
items[metric]context, and decimal helpers.