---
title: "Average reply quality per workspace"
method: GET
path: "/v1/admin/reply-quality/teams"
tags: ["admin"]
---

# Average reply quality per workspace

`GET /v1/admin/reply-quality/teams`

## Request

- Base URL: `https://api.patricia.app` (the document declares no server; this is the origin it was published from)
- URL: `https://api.patricia.app/v1/admin/reply-quality/teams`
- Auth: HTTP bearer

Every workspace with a scored reply in the window, busiest first, each with its scored count beside its averages. Read the count before the average: scored volume is very uneven across workspaces and a mean over a handful of replies is not a ranking. Omitting both bounds reads the last 12 weeks, the same span /trend defaults to; pass `all_time` to aggregate every scorecard ever written. The response echoes the window that was actually read.

## Query parameters

- `since` string, date-time, nullable: Window start (UTC). Defaults to 12 weeks before `until`.
- `until` string, date-time, nullable: Window end, exclusive (UTC). Defaults to now.
- `all_time` boolean: Drop the default lower bound and aggregate every scorecard on record. The upper bound is still captured, so the response can name the end it read and scorecards dated after the request are left out. An explicit `since` still applies and is not widened.
- `scorer_version` string: Restrict to one rubric version, or 'all' to compare across every version.
- `limit` integer: Maximum workspaces returned.

## Response `200`

Successful Response

- ReplyQualityTeams: Per-workspace quality for the window, busiest workspace first. ``since`` and ``until`` echo the window the rows were actually aggregated over, which is not always the window the caller asked for: omitting either bound applies the default span. Read them rather than the request, and label the table from them. ``until`` is always present: it is either the end the caller named or the instant this request captured, so it is not a "as of now" stamp. ``since`` is null only when the caller asked for every scorecard ever written, and the rows then reach back to the first one on record.
  - `since` string, date-time, nullable
  - `until` string, date-time, required: The end this aggregate actually read to. Always present, so a caller can label the table it got.
  - `scorer_version` string, nullable: Null when the window was read across every rubric version.
  - `teams` TeamQuality[], required
    - `tenant_id` string, uuid, required
    - `display_name` string, nullable: Null when the workspace record could not be resolved.
    - `scored` integer, required
    - `dimension_averages` object, required
    - `band_counts` object, required

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden. Inspect response body `code` for the specific reason (for example: PERMISSION_DENIED, EMAIL_NOT_VERIFIED, TENANT_ACCESS_REQUIRED, ROLE_UNRESOLVED)
- `404`: Not found
- `422`: Validation error

---

[API](https://skmtc.dev/patricia/apis/patricia-api.md) · [All operations](https://skmtc.dev/patricia/apis/patricia-api/llms.txt) · [OpenAPI document](https://skmtc.dev/patricia/apis/patricia-api/revisions/0dfb44495ea1?raw)
