Observability
The log, the trace, the numbers and the judges: what the runtime records for every call, and where to read it.
Everything a call did is written down as it happens, and you can read it four ways: the log, the trace, the numbers, and the judges. Nothing here needs a deploy or a line of code: it is what the runtime records for every call of every agent.
The log#
A call is a sequence of events: call.started, every turn.user and turn.agent with what was
said, every tool.call and tool.result with the arguments and what came back, the state.changed
after each, what memory recalled, what the knowledge base found, and at the end call.summary
(the cost, vendor by vendor) and call.score (the judges' verdicts). The console's call page shows
it live; the CLI prints it:
pinecall sessions --limit 5
pinecall sessions show call_7216eb82996a429f88ddd4173cff5c3f
call_7216eb82996a429f88ddd4173cff5c3f
outcome Para el lunes tengo dos horas libres con la doctora Vidal: a las nueve y a las once y media.
ended caller_hung_up · 55s · 4 turns
cost $0.0281
api.anthropic.com claude-haiku-5-5 13,369 input_tokens $0.0013
score consent held · grounded held · promises held
One line per thing that matters, then the verdicts. --json prints every event, for a pipe.
Your own code reads the same log as it is written: the SDK's observe streams every entry of an
agent's calls, folded with the state after each. Reading a call walks one
call in full.
The trace#
Every spoken call — a phone call, a voice call from the browser, a simulation with --voice — is
also an OpenTelemetry trace, written by the worker that holds the call's audio: a root span for
the session, then one span per model request (llm_node, with gen_ai.provider.name,
gen_ai.request.model, the tokens in and out, the time to the first token), per transcription,
per sentence spoken (tts_node, with the time to the first byte of audio) and per tool the agent
ran (function_tool). A written call — a chat, pinecall chat, a simulation without --voice —
has no worker and so no spans; its log, its numbers and its verdicts are written all the same.
Everything on this page is read from the log, never from the trace: the console's call page draws
each turn's timings as a waterfall, the pipeline screen each stage's median, the Observability
screen its charts — for written calls and spoken ones alike. The trace is for a tool of yours:
Datadog, Grafana, Langfuse, Honeycomb, Cekura, or an OpenTelemetry Collector you run, so a voice
agent's trace sits beside your backend's. It is off until the org names one, in the console at
Settings ▸ Telemetry or with pinecall telemetry set; the trace id is the call's own id, and
the call page's Trace card shows it: Export traces.
The numbers#
Every agent turn carries its latencies (llm_node_ttft, tts_node_ttfb, the end-of-turn delay,
the end-to-end time from the caller's last word to the agent's first), and every call its cost per
vendor. pinecall test prints llm_node_ttft per golden; the pipeline screen the medians; and the
runtime serves Prometheus metrics for whoever runs it.
The Observability screen#
The console's Observability screen reads like a dashboard: five cards at the top — calls, success rate (the share of verdicts the judges held), time to first token, mean call length, spend — each against the window before; then the window day by day, for every agent or the one in view, over 24 h, 7 d or 30 d, a day with nothing a gap and never a zero:
| chart | what it says |
|---|---|
| Duration | the mean length of the calls that ended, a day at a time |
| Failure modes | the judges that said no in the window, most often first, with how many of their verdicts broke |
| By agent | every agent's calls, success rate, spend and spend per minute over the window, when every agent is in view |
| Latency, end to end | the median and the p95 of the time from the caller's last word to the agent's first |
| Latency by stage, median · p95 | transcription, first token, first audio — each stage on its own line |
| Judges | the share of verdicts each judge held, one line per judge |
| Calls | how many a day, and how many a person took over |
| Tools | how many tool runs, and how many answered an error |
| Spend | every vendor, in US dollars |
| How calls ended | stacked bars a day, one colour per reason |
Hover a day to read its numbers. The same series is one door, GET /v1/insights/series, for a
dashboard of yours.
Monitors#
A monitor watches one number of the same series over 1, 7 or 30 days — end-to-end or first-token
latency at the median, the judges' held rate, the share a person took over, the share of tools that
failed, spend, calls — above or below a line, for every agent or one. The first seal of a call
that finds it on the wrong side fires monitor.fired on the agent's log, once a day, with the
value that crossed. Harness ▸ Monitors sets them and shows the last day each fired;
pinecall monitors does the same in a terminal, and the MCP tool monitors from an assistant.
A monitor that fires reaches the console's bell and the org's webhook: Alerts.
pinecall monitors add "slow answers" --metric e2e_median_s --above 2 --days 7
mon_3f9a1c2b4d5e · slow answers · e2e_median_s above 2 over 7 days · every agent
The judges#
A fixed panel reads every call at hang-up — consent (an irreversible tool ran only after a yes), grounded (what was said came from a tool or the knowledge), promises, and the persona's rule on a simulated call — plus the judges you write. A verdict that breaks opens a case; drift compares a judge's held-rate week over month and fails a job before a customer notices.