---
title: "Session-level usage summary (Enterprise)"
method: GET
path: "/api/v1/audit/session-summary"
tags: ["Audit"]
---

# Session-level usage summary (Enterprise)

`GET /api/v1/audit/session-summary`

## Request

- Base URL: `https://orchestrator.getaxonflow.com`
- URL: `https://orchestrator.getaxonflow.com/api/v1/audit/session-summary`
- Auth: none declared. Required headers: `X-Tenant-ID`
- TypeScript: <https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/docs/api/v1/audit/session-summary/get.ts> (a function with typed inputs; its response is checked against the schema)

**Enterprise** — session-level usage reporting (#2759). The Community
build mounts the same route but returns **501 Not Implemented**.

Buckets audit logs into per-session aggregates for the date window:
a bucket is **per-session** when `session_id` is present on its rows,
otherwise rows without a session id fall back to a **per-user-day**
bucket (the `day` field is set instead of `session_id`). Buckets are
capped at `bucket_limit` (most-recent activity first); `truncated` is
true when the window held more buckets than the cap — narrow the
window or raise `limit`. Drill into a bucket's raw events via
`POST /api/v1/audit/search` with its `session_id` (#2857).

The window start is clamped to the tenant's tier retention floor,
like `/api/v1/audit/search` and `/api/v1/audit/export`.

**`avg_latency_ms` is nullable** on the bucket and on every entry of
its `tools` array (#3433), paired with a `latency_sample_count`. `null`
means no row in that bucket carried a measurement, which is a different
fact from a measured zero and used to be coalesced onto it. A strict
deserializer binding it to a non-optional float will raise; see the
`SessionSummaryBucket` schema.

## Query parameters

- `start_date` string, date, required
- `end_date` string, date, required
- `user_email` string
- `limit` integer

## Headers

- `X-Tenant-ID` string, required

## Response `200`

Session summary buckets

- SessionSummaryResponse: GET /api/v1/audit/session-summary payload (Enterprise)
  - `tenant_id` string
  - `user_email` string: Echoed filter; omitted when not filtered
  - `start_date` string, date
  - `end_date` string, date
  - `buckets` SessionSummaryBucket[]
    - `session_id` string: Set when the bucket is a real session
    - `day` string: Set only for a per-user-day fallback bucket (YYYY-MM-DD)
    - `user_email` string
    - `tenant_id` string
    - `start_time` string, date-time
    - `end_time` string, date-time
    - `total` integer
    - `by_action` object: Per-bucket counts folded onto the canonical verdicts
    - `tools` object[]: Per-request_type usage within the bucket
      - `request_type` string
      - `count` integer
      - `tokens_used` integer
      - `cost` number, double
      - `avg_latency_ms` number, double, nullable: Mean latency in milliseconds over the rows of this request_type in this bucket that carried a measurement, or `null` when none did (#3433). Same contract as the bucket-level `avg_latency_ms` below, applied per request_type - and `null` is the NORMAL answer for a request_type whose writers record no duration, which is why it is per-request_type rather than only on the bucket.
      - `latency_sample_count` integer: How many rows of this request_type backed avg_latency_ms. 0 exactly when avg_latency_ms is null, and never greater than `count`.
    - `tokens_used` integer: Per-request token sum over governed audit rows (authoritative gateway view)
    - `cost` number, double
    - `avg_latency_ms` number, double, nullable: Mean latency in milliseconds over the rows in this bucket that carried a measurement, or `null` when none did (#3433, for parity with `/api/v1/audit/summary` and `/api/v1/audit/report`). `null` is not `0`. Whole planes record no duration by design (HITL approvals, workflow lifecycle rows, the connector-exec MCP closure), so a bucket whose traffic was entirely one of those has nothing to report. It used to be coalesced to 0, which reads exactly like a measured zero. Clients MUST accept null here; a strict deserializer binding this to a non-optional float will raise. It can also be BELOW 1: response_time_ms is whole milliseconds, so a decision completing in under a millisecond contributes a 0. Read latency_sample_count to tell "fast" from "empty". WHICH quantity this is differs from the compliance summary's tile. This surface sits beside provider tokens and cost, so it deliberately keeps the LLM plane's provider round trip in the average; the audit page's tile is the ENFORCEMENT number and excludes that plane. Naming the three quantities `response_time_ms` carries is tracked in #3431.
    - `latency_sample_count` integer: How many rows backed avg_latency_ms. 0 exactly when avg_latency_ms is null, and never greater than `total`.
    - `usage_metrics` SessionSummaryUsageMetrics: Optional Claude-export enrichment (#2852), sourced from the OTLP metrics ingest. Absent when no metric rows match the bucket. These are the CLI's own aggregates (everything the tool did, governed or not) and are deliberately nested rather than merged with the bucket-level tokens_used/cost, which remain the governed-gateway sums. tokens_used here counts input/output only; cache tokens are kept separately in cache_tokens and never inflate the headline.
      - `lines_of_code` integer
      - `active_time_seconds` number, double
      - `commits` integer
      - `pull_requests` integer
      - `tool_permission_decisions` object
        - `accept` integer
        - `reject` integer
      - `session_count` integer
      - `tokens_used` integer
      - `cache_tokens` integer
      - `cost_usd` number, double
  - `bucket_limit` integer: Effective bucket cap applied to this response
  - `truncated` boolean: True when the window held more buckets than bucket_limit — narrow the window or raise ?limit=

## Other responses

- `400`: Missing/invalid start_date or end_date, end_date before start_date, range over 1 year, or invalid limit
- `401`: Missing X-Tenant-ID header (tenant scoping required)
- `500`: Session summary query failed
- `501`: Community edition — session summary reporting is an Enterprise feature
- `503`: Audit subsystem unavailable

---

[API](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api.md) - [All operations](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getaxonflow/apis/axonflow-orchestrator-api/revisions/f408ef3ec9dd?raw)
