> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sempera.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Citation schemas

> The outcome fields frozen with each published version and how well each is captured.

A citation schema is the set of values an agent was published to capture from each call, frozen with that published version, together with how well each value has been captured. The values are the agent's **outcomes**: named facts such as "booked an appointment" or "service asked about", which Sempera reads from the transcript after each call together with the sentence that supports them (the `call.outcomes` webhook event carries them, [Webhooks](https://docs.sempera.org/webhooks.md)). Dispositions ([Dispositions](https://docs.sempera.org/dispositions.md)) are the per-call contract built on top of outcomes. Outcomes are defined on the agent's draft (the `outcomes` field of `PATCH /v1/agents/{id}/draft`, [Agents](https://docs.sempera.org/agents.md)) and published with it.

The routes only read what already exists: they define nothing and write nothing.

| Route | Scope | Notes |
| - | - | - |
| `GET /v1/citation_schemas` | `agents:read` | Schemas, newest published version first within each agent |
| `GET /v1/citation_schemas/list` | `agents:read` | The same list at a second path |
| `POST /v1/citation_schemas/backfill` | `agents:write` | `{"agent_id"}`. Answers one agent's schemas and quality scores in a single object |

The list takes `agent_id` (also `client`) to narrow it to one agent, `limit` (1 to 200, default 50) and `cursor`, and answers `{"object": "list", "data": [...], "has_more", "next_cursor"}`. Without `agent_id` it covers every active agent the credential can read. A version that defined no outcomes has no schema and is not listed. An agent the credential cannot read is `404 not_found`.

## A schema

```json theme={null}
{"id": "cit_northwind-barbers_4", "object": "citation_schema", "agent_id": "northwind-barbers", "version": 4,
 "source": "settings",
 "fields": [{"name": "booked", "type": "boolean", "description": "Booked an appointment"}],
 "quality": [{"version_number": 4, "key": "booked", "name": "Booked an appointment",
              "captured": 40, "found": 36, "corrected": 2, "accuracy": 95, "filled": 90}],
 "filled": 90, "created_at": "2026-09-28T09:15:42.386027Z"}
```

`version` is the agent's published version number and `created_at` is when that version was created. `source` is always `settings`. Each field's `name` is the outcome's key (the name a webhook receiver reads), `type` is `boolean`, `choice`, `text` or `number`, and `description` holds the outcome's display name, not its longer description.

`quality` has one row per outcome captured under that version. `captured` counts the calls where the outcome could be read, `found` the ones where a value with supporting text was found, and `corrected` the ones the owner marked wrong in the App. `filled` is `found` as a whole percentage of `captured`. `accuracy` is the whole percentage of captured values not corrected, so a value nobody has corrected counts as right: read it beside `captured`, because 100 over two calls means two calls. The schema's own `filled` is the average of its rows' `filled` values, rounded, and `null` when nothing was captured under that version.

## Backfill

`POST /v1/citation_schemas/backfill` needs `agents:write` and the `operator` or `owner` role, and answers `{"object": "citation_schema_backfill", "agent_id", "schemas", "quality"}`: the number of that agent's schemas and every quality row of them. Despite the name it changes nothing: it reads no new calls, scores nothing again and returns the figures the list route shows. An `agent_id` that is missing, unknown or not readable is `404 not_found`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.