OPEN SOURCE STANDARD · APACHE 2.0

Agent Usage Detail Record

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.

How it works

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.

01 · Shared run ID

Minted by the harness, passed to the router in request metadata, and echoed back. Every system that touches the run carries the same ID.

02 · Clear authority per field

The harness owns attribution: customer, environment, initiator. The router owns usage: tokens, provider. Each fact has exactly one source.

03 · Strict merge rules

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"
  }
}

Try it

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

Where it runs today

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.

NVIDIA NeMo Relay

Available today

OpenRouter

Available today

LiteLLM

Available today

In progress: Merge.dev · LangChain

The team behind this