Track Metered Usage
Mavvrik automatically captures and prices supported AI calls. Use metered usage for paid non-LLM resources that the SDK cannot derive automatically, such as OCR pages, external API calls, document-processing units, storage, or other per-unit services.
What metered usage records
Metered usage describes consumption:
metric + quantity + unit + optional rate
Example:
document.pages = 42 pages at $0.0015 per page
When rate_per_unit is supplied, Mavvrik can calculate:
cost = quantity × rate_per_unit
Use metered usage and signals for different purposes
-
Metered usage records the quantity and cost of a consumed resource.
-
Signal creates a named operation in the execution trace.
A signal is optional. Use it when the paid operation should appear as a distinct step in Home → Agentic → Sessions.
Do not add metered usage for a supported model call that Mavvrik already prices automatically.
Record metered usage in Python
import mvk_sdk as mvk
mvk.add_metered_usage([
{
"metric_kind": "document.pages",
"quantity": 42,
"uom": "page",
"metadata": {
"rate_per_unit": 0.0015,
"currency": "USD",
"provider": "aws-textract",
},
},
{
"metric_kind": "eligibility_api.request",
"quantity": 1,
"uom": "call",
"metadata": {
"rate_per_unit": 0.05,
"currency": "USD",
"provider": "eligibility-service",
},
},
])
Record metered usage in JavaScript / TypeScript
import { addMeteredUsage } from '@mavvrikai/sdk';
addMeteredUsage([
{
metricKind: 'document.pages',
quantity: 42,
uom: 'page',
metadata: {
rate_per_unit: 0.0015,
currency: 'USD',
provider: 'aws-textract',
},
},
]);
Python uses metric_kind; JavaScript / TypeScript uses metricKind. Pricing metadata uses rate_per_unit in both.
Add a named operation to the trace
Use a signal when the metered resource should also appear as a named step.
Python: function boundary
import mvk_sdk as mvk
from mvk_sdk.schema import MVKStepType
@mvk.signal(
name="verify_eligibility",
step_type=MVKStepType.TOOL,
tool_name="eligibility-service",
tags={"vendor": "availity"},
)
def verify_eligibility(member_ref, service_date):
result = eligibility_api.check(member_ref, service_date)
mvk.add_metered_usage([
{
"metric_kind": "eligibility_api.request",
"quantity": 1,
"uom": "call",
"metadata": {
"rate_per_unit": 0.05,
"currency": "USD",
"provider": "eligibility-service",
},
}
])
return result
Python: one stage inside a larger operation
from mvk_sdk.schema import MVKStepType
with mvk.create_signal(
name="lookup_provider",
step_type=MVKStepType.TOOL,
operation="lookup",
tool_name="provider-directory",
) as signal:
provider = directory.find(npi)
signal.set_attribute("provider.in_network", provider.in_network)
JavaScript / TypeScript
import { createSignal, addMeteredUsage, MVKStepType } from '@mavvrikai/sdk';
const signal = createSignal({
name: 'eligibility-check',
step_type: MVKStepType.TOOL,
operation: 'api_call',
vendor: 'eligibility-service',
});
try {
const result = await eligibilityApi.check(memberId);
addMeteredUsage([
{
metricKind: 'eligibility_api.request',
quantity: 1,
uom: 'call',
metadata: {
rate_per_unit: 0.05,
currency: 'USD',
provider: 'eligibility-service',
},
},
]);
return result;
} finally {
signal.end();
}
Manually created TypeScript signals must be ended on success and error paths. Use finally.
Signal API differences
|
Purpose |
Python |
JavaScript / TypeScript |
|---|---|---|
|
Decorator step type |
|
|
|
Python decorator tool name |
|
Use the TypeScript decorator configuration |
|
Manual signal step type |
|
|
|
Manual signal service/tool |
|
|
|
Metered usage metric |
|
|
|
Pricing metadata |
|
|
Use the exported MVKStepType enum where supported. Unsupported or misspelled parameters can be ignored without interrupting application execution, so verify exact field names when an expected attribute is missing.
Example: document-processing agent
import mvk_sdk as mvk
from mvk_sdk.schema import MVKStepType
from openai import OpenAI
client = OpenAI()
def process_document(customer_id, session_id, file_path):
with mvk.context(
customer_id=customer_id,
session_id=session_id,
use_case="document_processing",
):
with mvk.create_signal(
name="ocr-document",
step_type=MVKStepType.TOOL,
operation="ocr",
tool_name="aws-textract",
):
pages = run_ocr(file_path)
mvk.add_metered_usage([
{
"metric_kind": "document.pages",
"quantity": len(pages),
"uom": "page",
"metadata": {
"rate_per_unit": 0.0015,
"currency": "USD",
"provider": "aws-textract",
},
}
])
summary = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": f"Summarize: {pages}"}],
)
return summary.choices[0].message.content
The OCR operation is represented as a named trace step with metered page cost. The supported LLM call remains automatically captured and priced.
Verify metered usage
-
Run a workflow containing the metered operation.
-
Open Home → Agentic → Sessions and locate the test session.
-
If a signal was used, confirm the named operation appears.
-
Confirm the metric, quantity, and unit are present.
-
Open Home → Agentic → Cost and confirm the expected charge appears.
If usage is present without cost, confirm that rate_per_unit was supplied with the metered usage.