Skip to content
openaudrPublic

About

Agent Usage Detail Record — an open JSON standard for attributing and costing agent runs

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

15 stars

Watchers

0 watching

Forks

AUDR — Agent Usage Detail Record

spec docs Specification release PyPI Python versions npm License Apache 2.0

An open standard for recording who initiated an agent run and what each step cost, across every system the run passes through.

A single agent run touches several systems. The application knows the customer and the feature. The router knows the model, the tokens and the price. The provider knows the cache split. The harness knows whether the run actually resolved anything. Every layer is observable on its own, and none of them can tell you what that customer's agent cost you last month.

AUDR is one JSON record per metered operation, carrying enough identity and attribution that the records join.

{
  "spec_version": "1.1.0",
  "record_id": "01K4N8D2J4P7Q9R3S6T8V1W5XY",
  "emitter": { "component": "router", "name": "@audr/openrouter", "version": "0.5.1" },
  "timing": { "event_time": "2026-09-08T12:00:00.000Z" },
  "resource": {
    "provider": "anthropic",
    "type": "model",
    "name": "claude-sonnet-4-20250514",
    "operation": "generation",
    "modality": "text"
  },
  "run": { "run_id": "01K4N8B0M2C5F7H9J1L3N6P8QR", "span_id": "model-call-1" },
  "attribution": { "environment": "production", "account_id": "account-42" },
  "usage": { "llm": { "input_tokens": 1200, "output_tokens": 300 } }
}

How a run flows across components

Each participating layer — harness, router, provider — may emit its own AUDR record for an operation, each with its own record_id. In this example, the harness creates a run_id for the run and a distinct span_id for each operation, passing both along the request path. The sink deduplicates replayed records by record_id and joins records from different components that share (run.run_id, run.span_id); separate operations remain separate. Pricing the joined usage happens downstream and is outside AUDR. See SPEC.md §1.2, §1.4, and the Merge key definition for the normative description.

sequenceDiagram
    participant App as Application
    participant Harness as Agent Harness
    participant Router as Router / AI Gateway
    participant Provider as Model Provider
    participant Sink as Sink
    participant Rating as Rating<br/>(outside AUDR)

    App->>Harness: Start an agent run
    Harness->>Harness: Create run_id

    Note over Harness,Provider: span model-call-1: a model call
    Harness->>Router: Model request<br/>with run_id and span_id
    Router->>Provider: Forward request<br/>with the same IDs
    Provider-->>Router: Result and usage
    opt Provider also reports
        Provider--)Sink: AUDR record (provider's view)
    end
    Router--)Sink: AUDR record (router's view)
    Router-->>Harness: Result / tool request
    Harness--)Sink: AUDR record (harness's view)

    Note over Harness: span tool-call-2<br/>A tool in the same run
    Harness->>Harness: Run tool<br/>parent_span_id: model-call-1
    Harness--)Sink: AUDR record (tool usage)
    Harness-->>App: Response

    Note over Sink: Deduplicate replays by record_id<br/>Join records sharing<br/>run_id and span_id
    Sink->>Rating: Joined usage, ready to price
Loading

Start here

Path Contains
spec/ The standard: SPEC.md to implement it, audr.schema.json to validate records, examples/record.json for a complete record
conformance/ Language-neutral fixtures every implementation must reproduce
adapters/ Things that produce records — the Python and TypeScript SDKs and runtime adapters
sinks/ Things that consume records — destinations such as Chargebee and Lago
tools/ The specification generator and the repository checks, driven by the Makefile

The schema's canonical URL is its $id:

https://openaudr.dev/spec/v1.1.0/audr.schema.json

Validate records with a JSON Schema Draft 2020-12 validator. Repository setup, verification and specification generation are documented in CONTRIBUTING.md.

Emitting records

Three parts work together. An adapter observes an agent runtime and builds a record per metered operation; the core SDK validates, batches and accounts for records through a Client; a sink delivers each batch to a destination. Install the core and a sink, wrap the sink in a client, and either call client.record() yourself or let an adapter do it.

pip install audr audr-sink-chargebee
import asyncio

import audr
from audr_sink_chargebee import ChargebeeSink

# The record shown above, built with the SDK. record_id, spec_version and
# timing.event_time are defaulted; Chargebee additionally routes on subscription_id.
record = audr.AUDR(
    timing=audr.Timing(),
    resource=audr.Resource(
        provider="anthropic",
        type="model",
        name="claude-sonnet-4-20250514",
        operation="generation",
        modality="text",
    ),
    run=audr.Run(run_id="01K4N8B0M2C5F7H9J1L3N6P8QR", span_id="model-call-1"),
    attribution=audr.Attribution(
        environment="production", account_id="account-42", subscription_id="sub-42"
    ),
    usage=audr.Usage(llm=audr.LlmUsage(input_tokens=1200, output_tokens=300)),
)


async def main() -> None:
    sink = ChargebeeSink(site="acme", api_key="cb_live_...")  # any Sink: a file, a queue, Chargebee
    async with audr.Client(
        sink,
        emitter=audr.Emitter(component="router", name="openrouter", version="1.12.1"),
    ) as client:
        result = client.record(record)  # an adapter makes this call on your behalf
        assert result.queued, result.issues
    print(client.stats)


asyncio.run(main())
Part Reference implementation Guide
Core SDK audr (Python)
@openaudr/audr (TypeScript)
adapters/core/README.md — the Client, the sink contract, delivery states
Adapters audr-adapter-litellm (Python)
audr-adapter-nemo-relay (Python)
@openaudr/audr-adapter-merge-gateway (TypeScript)
@openaudr/audr-adapter-openrouter (TypeScript)
@openaudr/audr-adapter-vercel-ai (TypeScript)
@openaudr/audr-adapter-mastra (TypeScript)
adapters/README.md
Sinks audr-sink-chargebee (Python)
@openaudr/audr-sink-chargebee (TypeScript)
@openaudr/audr-sink-lago (TypeScript)
sinks/README.md

Adapters, sinks and tools maintained outside this repository are listed in IMPLEMENTATIONS.md.

Status

The current specification version is 1.0.0.

Governance

AUDR was drafted at Chargebee, and is being improved with collaboration across the ecosystem. Granular cost and usage instrumentation are foundational to agent unit economics — the infrastructure every team building or monetizing agents will need. We believe that infrastructure should be open, neutral, and community-owned. As adoption grows, the goal is to move cost governance to an independent foundation.

Stewarded by Chargebee. Contact us at audr@chargebee.com.

Contributing

Tell us where AUDR breaks for a cost model you have and we haven't imagined. Open an issue or email audr@chargebee.com. See CONTRIBUTING.md; participation is governed by the Code of Conduct.

Security

To report a vulnerability, follow SECURITY.md. It also states the data-handling rules the format depends on: records carry no prompt content, no key material, and no PII.

License

Apache 2.0. See NOTICE.

About

Agent Usage Detail Record — an open JSON standard for attributing and costing agent runs

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

15 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages