# The management client

A generated, typed client for the admin API, shipped beside each SDK but versioned and scoped separately.

Source: https://tokentriage.com/docs/sdks/management

---
import Callout from '../../../components/Callout.astro';
import NextSteps from '../../../components/NextSteps.astro';
import Details from '../../../components/Details.astro';
import CodeTabs from '../../../components/CodeTabs.astro';

`ledger.fetch` answers one question: what did this request cost? The admin plane answers several
hundred more, and the management client is the typed way to ask them from code.

Reach for it when you are scripting the control plane — exporting spend by tenant, minting virtual
keys, reading anomaly findings, driving a config change from CI. Reach for `ledger.fetch` when you
want a costed row and nothing else.

## Getting a client

It ships inside the same package, under its own import path, and is not re-exported from the root.

<CodeTabs>
  <Fragment slot="python">
  ```python
  from tokentriage.management import Client

  client = Client("http://127.0.0.1:9090")     # or $TOKENTRIAGE_ADMIN_URL
  caps = client.meta.capabilities_get()
  print(caps.management_api.version)
  ```
  </Fragment>
  <Fragment slot="typescript">
  ```ts
  import { Client } from "tokentriage/management";

  const client = new Client("http://127.0.0.1:9090");
  const caps = await client.meta.capabilitiesGet();
  console.log(caps.managementApi.version);
  ```
  </Fragment>
</CodeTabs>

```text
2.19
```

That number is the **management contract version**, and it is not the SDK's contract version. The
instrumentation contract is at 1 and moves rarely; the management contract tracks the admin API
and moves whenever a resource is added. Asking the server for its version is the first call worth
making, because a client generated against 2.19 talking to an older server will find operations
that are not there.

## What is on it

Calls are grouped by resource, matching the server's own structure:

```text
alerts · analytics · annotation_queue · annotations · anomalies · audit · auth · budgets
cache · config · content · control · costanalytics · evals · events · evidence · exports
feedback · fleet · governance · guardrails · instances · judges · meta · outcomes · pricing
providers · quality · recommendations · reconcile · schedules · share · stream · tokens
users · views · webhooks
```

Thirty-seven groups, each carrying its own operations and typed models. The
[API reference](/api) renders the same surface from the same OpenAPI description, so use it to
find the operation you want and this client to call it.

<Callout type="note">
`outcomes` and `feedback` appear both here and on
[the instrumentation SDK](/docs/sdks/outcomes). They are the same endpoints. The instrumentation
versions are narrower: they take a receipt, run the credential-containment protocol,
and withhold the fields a client should not assert. Prefer them for writing quality signals from
an application, and use the management client when you are scripting the plane itself.
</Callout>

## Every file here is generated

There is no hand-written module in either management package. Both are emitted from the server's
own resource registry, which is the same source the published OpenAPI description is generated
from.

That arrangement is what makes one check sufficient. A regeneration gate fails the build on any
hand edit or stale file, and a cross-projection test compares the bindings to the contract field
by field, so a divergence is a build failure rather than a runtime surprise.

Two consequences for you. Do not edit these files; regenerate them. And an operation missing from
the client is missing from the server's registry too, rather than being an oversight in one
language.

## Credentials

The management token is `TOKENTRIAGE_ADMIN_TOKEN`, from the environment, with no keyword argument
anywhere — the same rule as the instrumentation SDK, because this package reuses that transport.

The token is attached only after the far end has identified itself as this management plane, and
it appears in no log line, exception message or repr. [The credential
protocol](/docs/sdks/ledger#the-credential-protocol) is the same one described for the ledger.

<Details summary="Why this is a separate import path rather than part of the SDK">

The instrumentation surface is frozen for 1.0 and kept small: a developer should be able to
read it in one sitting and know what it can do to their process. It has a stable contract version,
zero dependencies, and no network calls outside two explicit ones.

The management client is a different thing. It is large, it tracks a faster-moving contract, and
it exists to talk to the control plane rather than to instrument a request path. Merging them
would mean the frozen surface grew every time an admin resource was added.

So it lives at `tokentriage.management` and `tokentriage/management`, is versioned by the
management contract rather than the instrumentation one, and nothing from it is re-exported from
the package root. Importing the SDK does not import it.

</Details>

## What can go wrong

| Symptom | Cause | Fix |
|---|---|---|
| an operation is missing | client generated against a different contract | compare `capabilities_get()` with your client's version |
| `AdminAuthRequired` | the admin plane wants a bearer | set `TOKENTRIAGE_ADMIN_TOKEN` |
| `PlaneCollision` | you passed a data-plane URL | pass the admin plane address |
| a typed model has an unexpected field | the server is newer than the client | regenerate, or read the untyped payload |

<NextSteps items={[
  { title: 'Management API reference', href: '/api', description: 'Every operation this client exposes, rendered from the same description it is generated from.' },
  { title: 'Fetching a costed row', href: '/docs/sdks/ledger', description: 'The narrower call, when a costed row is all you need.' },
  { title: 'Outcomes and feedback', href: '/docs/sdks/outcomes', description: 'The instrumentation-side versions of two endpoints that appear here too.' },
  { title: 'Admin plane security', href: '/docs/operate/security', description: 'Who should be able to reach the plane this client talks to.' }
]} />
