Patter ships opt-in OpenTelemetry tracing that covers the four hot spots on the voice pipeline: STT, LLM, TTS, and tool calls. Every span carries the currentDocumentation Index
Fetch the complete documentation index at: https://patter-06b046ce-feat-observability-otel-attrs-0-6-1.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
getpatter.call.id so you can group by call in your backend.
Enable tracing
Tracing is disabled by default. Install the optional dependency and set the env flag:init_tracing once at process start — typically from the same module that creates your Patter client:
PATTER_OTEL_ENABLED is not set, init_tracing returns False and every span becomes a no-op — zero cost when disabled.
Emitted spans
| Span name | Fires | Attributes |
|---|---|---|
getpatter.call | One per call (root span) | getpatter.call.id, getpatter.call.direction, getpatter.call.provider_mode |
getpatter.stt | One per final transcript | getpatter.stt.text_len, getpatter.stt.confidence |
getpatter.endpoint | One per detected end-of-utterance | getpatter.endpoint.silence_ms |
getpatter.llm | One per LLM iteration (incl. tool rounds) — wraps the pipeline LLM call so TTFT is measured per turn | getpatter.llm.iteration, getpatter.llm.history_size, getpatter.llm.ttft_ms |
getpatter.tts | One per synthesized sentence | getpatter.tts.text_len |
getpatter.bargein | One per barge-in event | getpatter.bargein.cancelled_text_len |
getpatter.tool | One per tool invocation | getpatter.tool.name, getpatter.tool.transport |
getpatter.* namespace as Python (the legacy patter.* names were normalised in 0.5.3 — both SDKs now emit identical span names so a single dashboard query works across runtimes).
PII hygiene
Patter never exports user utterances, tool payloads, or LLM content as span attributes. Only sizes, counts, and identifiers are emitted — traces are safe to ship to a shared Jaeger / Honeycomb / Grafana Cloud instance.Cost and latency attributes (patter.*)
Beyond the spans listed above, every billable hot path stamps patter.cost.* and patter.latency.* attributes on its span starting in 0.6.0. External aggregators (e.g. the patter-agent-runner acceptance suite) read these directly to compute per-call USD and latency without touching the SDK’s pricing table.
| Attribute | Type | Where it fires |
|---|---|---|
patter.call_id, patter.side | str | Every cost/latency span (routing tags) |
patter.cost.telephony_minutes, patter.telephony, patter.direction | float / str | Twilio + Telnyx adapters on call end |
patter.cost.stt_seconds, patter.stt.provider | float / str | Each final transcript (Deepgram, AssemblyAI, Whisper, OpenAI-Transcribe, Soniox, Speechmatics, Cartesia) |
patter.cost.tts_chars, patter.tts.provider | int / str | Each synthesis (ElevenLabs, OpenAI, Cartesia, LMNT, Rime) |
patter.cost.llm_input_tokens, patter.cost.llm_output_tokens, patter.llm.provider | int / int / str | Each completion (OpenAI, Anthropic, Google Gemini, Groq, Cerebras) |
patter.cost.realtime_minutes, patter.realtime.provider | float / str | OpenAI Realtime + ElevenLabs ConvAI on session end |
patter.latency.ttfb_ms, patter.latency.turn_ms | float | Per completed agent turn (pipeline mode) |
patter.call_id, patter.side) propagate via asyncio-safe ContextVars set at the top of the per-call WebSocket bridge, so all spans emitted under a call inherit them automatically — no manual wiring per span.
Attach a custom exporter (Patter._attach_span_exporter)
Embedding tools that observe Patter from the outside can wire their own exporter without touching PATTER_OTEL_ENABLED or init_tracing:
side is stamped on every cost/latency span this Patter instance emits during its call lifecycle. It exists to disambiguate two-Patter-instances-in-one-process layouts (e.g. driver vs unit-under-test in agent-to-agent acceptance tests). Default is "uut" if you only have one instance.
The leading underscore signals this is not part of the customer-facing API surface — it is a stable, public-but-underscore hook for tooling.
Shutdown
Callshutdown_tracing() during graceful shutdown to flush any pending spans:
Troubleshooting
No spans appear → confirmPATTER_OTEL_ENABLED=1 is set in the process that calls init_tracing. Quick check:
otel/opentelemetry-collector-contrib or enable the HTTP receiver in your collector config.
Tracing has full TypeScript parity since 0.5.3 — span names, attributes, and PII hygiene are identical. See TS Tracing.

