September 2026 release is live Read More

Track Metered Usage

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

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

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

Python
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

Python
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

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

step_type

stepType

Python decorator tool name

tool_name

Use the TypeScript decorator configuration

Manual signal step type

step_type

step_type

Manual signal service/tool

tool_name

vendor

Metered usage metric

metric_kind

metricKind

Pricing metadata

rate_per_unit

rate_per_unit

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

Python
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

  1. Run a workflow containing the metered operation.

  2. Open Home → Agentic → Sessions and locate the test session.

  3. If a signal was used, confirm the named operation appears.

  4. Confirm the metric, quantity, and unit are present.

  5. 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.