Product · Unmetered traffic

The provider's own ledger checks yours.

Two ledgers, or a claim. The gateway meters every request from what the provider reported on the wire. That ledger cannot notice its own blind spots: a colleague's notebook on the same account, a usage field a new model added, a stream that settled against a guess. A second ledger from the provider's own usage API is the check on it.

the second ledger
the provider's own admin usage API
the cadence
a round every hour, a day judged 48 hours after it closes
a breach needs both
2% of the larger side, and 10,000 tokens
the alert
pistra_reconcile_judged_day_seconds going stale

The audit of AI you do know about

The category beside this one sells discovery: AI nobody approved, a consumer chat tool in a browser, a vendor procurement never saw, a SaaS product with a model behind it. That is a different product. This audit reads the provider organisations you hold an admin credential for, so it sees nothing in a browser, nothing at another vendor and nothing in an organisation you did not name.

What it answers is narrower and checkable. On the account you already govern, did every request go through the gateway. Discovery finds the accounts nobody told you about. This says whether the one you did tell it about is whole, which is the claim a control depends on and the one no ledger can make about itself.

The answer you get is a number you can defend: how far the gateway's day and the provider's day diverged, per token class, with a threshold agreed in advance.

How a day is judged

A round runs every hour. A day is judged 48 hours after it closes, because the usage APIs trail and restate recent buckets. Four token classes are compared per day, and a class breaches when it disagrees by both a ratio, 2% of the larger side by default, and a floor, 10,000 tokens by default. Two thresholds, because a ratio alone pages someone over a quiet Sunday and a floor alone never fires on a busy account. The classes follow the provider's own convention on both sides, so the ledgers compare within a provider and never across one.

Set api_key_ids when you can. Scoped to the keys the gateway routes through, drift in either direction is a hard signal. Unscoped, the query covers the whole organisation, and drift above what was metered may be a colleague's notebook on the same account: a real finding the first time and noise every time after. Audit your metering against the provider.

Read the sign first

Which ledger is larger is the first thing a breach says. Metered above provider is the gateway believing it sent more than the provider billed, which is double counting, and it is rare enough to be worth a bug report. Provider above metered is the gateway having missed spend, and that is the direction this page exists for.

Even then it is usually not missing traffic. A usage field the scanner does not read, a stream that settled against an estimate, a WebSocket session whose frame decoder desynced and disabled itself: each leaves the same shape in the same direction. Audit your metering ranks the four causes in the order to check them, with what distinguishes one from another.

How to read a breach

A breach is a question rather than an alarm. It says two ledgers disagree by more than the tolerance. It does not say which one is wrong.

The alert is staleness

A poller that is stuck reports a reassuring drift of zero forever, and a drift gauge alone would call that healthy. So the gauge to alert on is the most recently judged day going stale past the maturity lag plus the interval, and the drift is read once that day is fresh. The three gauges and what each one says are in the metrics reference.

Every node answers

In a cluster every node meters and only the raft leader polls, and the result of polling is replicated. The verdicts are recomputed on every node from two replicated ledgers with the arithmetic the poller judged with, so the answer is the same answer on each and survives a leadership change. The last failed round is written down rather than kept in the leader's memory, because a broken admin credential tends to cause the failover that would lose it. Before anything is configured the endpoint answers 501, so "not set up" and "set up and quiet" never look alike.

Threat model

The asset is the claim that every request on a provider account went through the gateway. Nobody has to attack it. A colleague with the same API key in a notebook, a key minted in the same organisation and called directly, a scanner that missed a usage field: each leaves the gateway's ledger short without leaving a trace in it. The control is a second ledger, built from the provider's admin usage API, compared with the gateway's own per day and per token class, and a verdict when they disagree by more than you said you would tolerate. The limit is the provider: the audit reads one organisation you hold an admin credential for, on a provider that publishes a usage API. Most OpenAI-compatible vendors publish none.

The entry this section expands, and the ten beside it: threats and limits.

What this does not do

  • Drift under the tolerance is invisible. A class breaches only when it clears both 2% of the larger side and 10,000 tokens. Traffic leaking steadily below either threshold is real and never fires, and lowering them trades that for a page over every quiet Sunday.
  • It is daily, per provider, per class. It cannot attribute drift to a virtual key, a model or a route. The provider's report is account-scoped and the gateway's is not, and the only axis they share is the day. When a breach points at unmetered traffic, the audit says that much, and the gateway's own logs and record are the next stop.
  • It needs a usage API and an admin credential. Anthropic and OpenAI publish one. A provider absent from the list is not audited at all, and a provider with no usage API cannot be.
  • It says nothing about budgets. A budget bucket is enforcement rather than accounting, and has its own endpoint and its own gauge.