Skip to main content

Metrics & Cost Tracking

Patter automatically tracks cost and latency for every call, broken down by provider component (STT, TTS, LLM, telephony).

How It Works

Metrics are collected automatically during calls. When a call ends, the onCallEnd callback receives a CallMetrics object with the full breakdown:

Cost Breakdown

The CostBreakdown object provides per-component costs in USD:

Latency Breakdown

The LatencyBreakdown object provides per-component latency in milliseconds: CallMetrics exposes the full distribution: latency_avg, latency_p50 (median / typical UX), latency_p90 (steady-state outliers), latency_p95 (SLA), and latency_p99 (cold-start outliers).

Per-Turn Metrics

Each conversation turn is tracked individually:

Custom Pricing

Override default provider pricing estimates:

PricingUnit

The pricing tables expose a PricingUnit constant so overrides don’t depend on raw strings:
Shipped as a const object plus value-union type so it is tree-shakeable. Mirrored byte-for-byte by the Python PricingUnit StrEnum.

Model-Aware Pricing

Patter’s pricing tables are model-aware: every entry in DEFAULT_PRICING carries provider-level defaults plus an optional models map keyed by model identifier. When the agent’s adapter exposes a model field, the metrics layer threads it through the cost-calc functions and the dashboard bills with model accuracy out of the box — no manual override required.

How resolution works

The cost-calc helpers (calculateSttCost, calculateTtsCost, calculateRealtimeCost, calculateRealtimeCachedSavings) accept an optional final model parameter. The exported resolveProviderRates(config, model) helper merges per-model overrides on top of provider defaults using:
  1. Exact match in the provider’s models map.
  2. Longest-prefix matchgpt-realtime-2-2026-05-08 resolves against gpt-realtime-2.
  3. Provider defaults — fallback when the model is unknown or omitted.
CallMetricsAccumulator auto-tracks sttModel, ttsModel, and realtimeModel from the agent’s adapter model field (agent.stt.model, agent.tts.model, agent.model for Realtime). On every recordRealtimeUsage(usage) call the realtime model is also pulled from the response.done payload itself, overriding the call-level default — so mid-call model switches are billed correctly.
The optional model argument defaults to undefined, which preserves the legacy provider-rate behaviour. Existing callers compile and run unchanged.

Example A — Just select a model

The most common case: pick a model on your adapter, and Patter bills the right rate automatically.

Example B — Override one model, keep siblings intact

mergePricing overlays the nested models map shallowly. Overriding a single model leaves the other rates inside the same provider untouched.

Example C — Register a brand-new model rate

Add a model that isn’t in the built-in table without touching SDK source.

Default Pricing (2026.3)

Provider-level defaults are listed below. Per-model rates live under DEFAULT_PRICING[provider].models and are auto-resolved when the adapter exposes its model identifier.

STT — per-model rates

TTS — per-model rates

OpenAI Realtime — per-model rates

gpt-4o-realtime-preview is roughly 10x the cost of gpt-realtime-mini for audio. Switching realtime models has direct billing impact — confirm the model on agent.realtime.model matches the rate you expect.

xAI Realtime — rates

Unlike OpenAI Realtime (token-based), the xAI Grok Voice Agent is billed per minute of session audio, so Patter meters it from the call’s durationSeconds rather than token counts.
Twilio defaults match US inbound local. Override pricing.twilio.price for US toll-free inbound (~0.022/min)orUSoutboundlocal( 0.022/min) or US outbound local (~0.014/min). Default pricing is based on publicly listed provider rates and may become stale — check the provider’s pricing page or pass your own overrides for authoritative numbers.

Real-Time Metrics

Use the onMetrics callback for live cost updates during a call:

Data Types

CallMetrics

TurnMetrics