---
title: "Agent Telemetry Summary"
method: GET
path: "/v1/agent-telemetry/summary"
tags: ["agent-telemetry"]
---

# Agent Telemetry Summary

`GET /v1/agent-telemetry/summary`

What the coding agent produced in a window, and what it cost (standalone).

Range-bounded like `/v1/usage/summary` (default last 30 days, hard-capped),
so the aggregates stay served by the timestamp index. Returns the outcome
totals (commits, pull requests, lines changed, active time), the behavioral
counts already captured from the logs signal (tool calls and their mix, tool
accept/reject, turns, API errors), the recorded spend over the same scope,
and the derived per-unit measures: cost per commit / pull request / line,
spend per active hour, acceptance rate, turns per session, and error rate.
Each measure is null rather than an error when its denominator is zero.
Filterable by user, API key, and `session_label`, so cost per outcome can be
read for one agent session as well as for a whole window.

The spend side is every usage row in scope, not only the agent's: unfiltered,
that includes traffic from clients that never reported telemetry, so a
per-outcome measure read over a whole deployment answers "what did this
deployment spend per commit", not "what did the agent spend per commit".
Filter by user, API key, or session to divide only the matching spend.

Outcome metrics are stored exactly as the agent reported them, so a
cumulative counter is converted to a window increment here, at read time,
diffed per series generation: a re-exported total adds nothing, and a counter
reset never reads as negative work. Master-key only.

## Query parameters

- `start_date` string, date-time, nullable — Return rows with timestamp >= start_date (ISO 8601 or Unix epoch seconds)
- `end_date` string, date-time, nullable — Return rows with timestamp < end_date (ISO 8601 or Unix epoch seconds)
- `user_id` string[], nullable — Filter to one or more users; repeatable (user_id=a&user_id=b). Several values match any of them. At most 50 per call.
- `api_key_id` string[], nullable — Filter to one or more API key ids; repeatable (api_key_id=a&api_key_id=b). Several values match any of them. At most 50 per call.
- `session_label` string, nullable — Filter to a single agent session. Matches agent_telemetry.session_label and, on the usage side of the join, the usage_logs.source_label that /v1/usage/summary filters on
- `bucket` 'hour' | 'day' — Time-series granularity: 'hour' or 'day'

## Response `200`

Successful Response

- AgentTelemetrySummary — Agent outcomes and behavior for the window, joined against recorded spend.
  - `behavior` AgentTelemetryBehavior, required — Counts from the behavioral events already captured on the logs signal.
    - `api_errors` integer
    - `by_tool` AgentTelemetryToolRow[]
      - `calls` integer, required
      - `tool` string, nullable, required
    - `sessions` integer
    - `tool_accepts` integer
    - `tool_calls` integer
    - `tool_rejects` integer
    - `turns` integer
  - `bucket` 'hour' | 'day', required
  - `end_date` string, required
  - `measures` AgentTelemetryMeasures, required — Cost and quality per unit of work. Each is null when its denominator is zero. ``edit_acceptance_rate`` and ``tool_acceptance_rate`` are the same quantity today, both derived from the ``tool_decision`` event: the agent's own ``code_edit_tool.decision`` metric is deliberately never stored, since ``tool_decision`` already carries that accept/reject signal. Both names are reported so a caller reading either vocabulary gets the right number.
    - `cost_per_commit` number, nullable
    - `cost_per_line` number, nullable
    - `cost_per_pull_request` number, nullable
    - `edit_acceptance_rate` number, nullable
    - `error_rate` number, nullable
    - `spend_per_active_hour` number, nullable
    - `tool_acceptance_rate` number, nullable
    - `turns_per_session` number, nullable
  - `outcomes` AgentTelemetryOutcomes, required — How much work the agent produced inside the window. Each value is the read-time increment for its metric: a delta series is summed, a cumulative one is diffed per series generation, so a counter that is re-reported in full on every export is never counted twice. ``lines_of_code`` sums the added and removed series, which are stored separately. ``active_time`` is in seconds, as the agent reports it.
    - `active_time` number
    - `commits` number
    - `lines_of_code` number
    - `pull_requests` number
  - `series` AgentTelemetrySeriesPoint[], required
    - `active_time` number
    - `api_errors` integer
    - `bucket_start` string, required
    - `commits` number
    - `cost` number
    - `lines_of_code` number
    - `pull_requests` number
    - `tool_calls` integer
    - `turns` integer
  - `start_date` string, required
  - `usage` AgentTelemetryUsage, required — The recorded spend the measures below divide, reported so they can be checked.
    - `cost` number
    - `requests` integer

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/mozilla-ai/apis/otari.md) · [All operations](https://skmtc.net/mozilla-ai/apis/otari/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mozilla-ai/otari/revisions/3945cde96091/schema)
