OPEN SOURCE STANDARD · APACHE 2.0
An open standard for recording what your agents spend and who it was for, across every system a run passes through.
<aside> →
Read the spec · GitHub · Apache 2.0
</aside>
A single agent run touches multiple systems. The application knows the customer and the feature. The router knows the tokens and the cost. The tools know what they executed. Without a shared way to join these, usage data is orphaned from the business context that gives it meaning.
A run can be fully observable at every individual layer and still leave you without a single end-to-end record of what it cost.
The telecom industry solved this with the Call Detail Record, an open standard carriers converged on so a call's attributes could be captured and exchanged in a common format, independent of any single carrier's systems. AUDR is built on the same principle: a common record for agent runs that any harness, router, or billing system can emit and ingest.
A record carries the raw counts that drive cost—tokens, tool calls, seconds of compute—alongside the business context that says whose cost it is: customer, feature, environment. Every layer keeps reporting what it already reports. AUDR adds three rules that let those reports come together into one record.
Minted by the harness, passed to the router in request metadata, and echoed back. Every system that touches the run carries the same ID.
The harness owns attribution: customer, environment, initiator. The router owns usage: tokens, provider. Each fact has exactly one source.
The sink assembles records sharing a run and span ID. No component rewrites another's block. Conflicts are rejected, and a correction is a new record, never a mutation.
// one record, one authoritative source per field
{
"run": {
"run_id": "run_8f2a1c", // minted by harness
"span_id": "span_4b91"
},
"attribution": {
"customer_id": "acme-corp", // source: harness
"initiator": "end_user"
},
"usage": {
"llm": {
"input_tokens": 1204,
"output_tokens": 318
} // source: router
},
"emitter": {
"component": "router"
}
}
Wrapping the router gets you cost and attribution per call, but not run-level rollup, since only the harness knows when a run has ended. Wrapping the harness ties those calls into one run, with outcomes and sub-agent hierarchy attached.
import { withAUDR } from '@audr/openrouter'
const router = withAUDR(openrouter, {
customer_id: req.customerId,
environment: 'production',
initiator: 'end_user',
sink: 'file://./audr.jsonl'
})
// nothing else changes; every call now emits a record
A record can be carried as an OpenTelemetry span, so if you're already running that pipeline, adopting AUDR doesn't mean replacing it. Adapters exist today at every layer a run passes through.
Available today
Available today
Available today
In progress: Merge.dev · LangChain