AU AUDRv0.5 Contents ↓

Technical Specification · Version 0.5

Agent Usage Detail Record (AUDR)

A JSON record format for agent cost monitoring and monetization.

Attribution

This document is a technical specification of the Agent Usage Detail Record v0.5 JSON Schema. Its field semantics, constraints, and requirement language are derived from the AUDR schema.

Version 0.5

The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL indicate requirement levels as described by RFC 2119.

1. Introduction

1.1 Scope

This specification defines the Agent Usage Detail Record (AUDR), a JSON object that describes one metered operation in an agent system. A record identifies its emitter and resource, reports raw model or tool usage, associates the operation with a run, and carries attribution required for downstream cost allocation. A record MAY include an informational cost assertion.

1.2 Architecture

A typical AUDR-enabled agent workflow has five logical components:

  1. Agent Harness: Runs the agent and performs tasks by requesting model operations and invoking tools. It manages sessions, tool execution and supplies run hierarchy.
  2. Router / AI Gateway: Selects a model and provider through a normalized provider interface, forwards each operation, and captures resource and usage data.
  3. Provider: Executes the model operation or provider-hosted tool and returns the result with native usage and cost observations when available.
  4. Sink: The ingest layer that receives emitted usage records, then validates, deduplicates, merges, and stores them.
  5. Rating: The downstream calculation of a billable amount from raw usage and billing configuration.

The application invokes the agent harness. Each metered operation passes from the agent harness through the router role to the provider; roles MAY be co-located, participating components MAY emit independent AUDR records, and the sink assembles records that share a run.run_id and run.span_id. Rating consumes stored records and is out of scope for this specification.

1.3 Out of Scope

  • Rated customer amounts, invoice generation, and revenue recognition.
  • Sink operational policies such as orphan wait duration and merge timing.
  • Provider registry contents beyond the resource.provider slug convention.
  • Agent internal state records and observability event formats.

1.4 Record Processing Model

Multiple components MAY describe the same metered operation or agentic run. A sink assembles those observations using the pair run.run_id and run.span_id. Each emitted record has an independent record_id for deduplication and correction processing. Downstream rating components MAY use or ignore the asserted cost object according to its own billing configuration.

2. Definitions

Emitter
The component that wrote the record, identified by emitter.component.
Harness
The agent runtime or orchestration layer that runs the agent loop. It builds prompts, calls the model, executes tools, returns the results, and manages session state, context, and tool permissions.
Merge key
The pair (run.run_id, run.span_id). It groups records from different emitters that describe the same metered operation.
Metered operation
One model operation, tool execution, or retrieval identified by a unique run_id and span_id pair.
Provider
The vendor or platform that serves the model or executes the metered tool.
Rating
The downstream calculation of a billable amount from raw usage and billing configuration.
Record
One emitted AUDR JSON object with its own record_id.
Router / AI Gateway
The layer that routes model requests to providers. This provides a unified interface for agent harness to invoke multiple provider models. The router tracks token consumption and optionally has a fallback mechanism for optimizing model calls or during outages.
SDK
The client library role responsible for record construction fields such as spec_version and record_id.
Sink
The ingest layer that validates, deduplicates, merges, and stores the usage records. It is distinct from Rating in that Sink is responsible only for validating and storing records, not for calculating a billable amount.
Tools
External capabilities invoked by an agent harness. Each request to one of these capabilities is a tool invocation. Examples include web search, code execution, file access, retrieval, database queries, and API calls.

3. Specification

3.1 Format

An AUDR record is represented as a JSON object. Property names are case-sensitive. Objects use fixed fields unless a patterned x_* extension is explicitly defined. All other additional properties are invalid.

3.2 Conformance

A conformant record MUST contain all top-level required properties and MUST satisfy the cross-field operation constraints in section 3.13.

3.3 Validation Boundaries

JSON Schema validation does not enforce every AUDR invariant. Conformant sinks and conformance tooling are responsible for the following requirements:

  • A record missing attribution.environment MUST be ignored and MUST NOT be rated.
  • Sinks MUST apply record_id deduplication and correction replacement.
  • Each block has one writer for a given run_id and span_id merge key.
  • A merge key MUST identify one metered operation.
  • A correction MUST use the same emitter.component as the corrected record.
  • Rating components MAY check cost-component consistency without overwriting cost.total_cost.

3.4 AUDR Record Object

This is the root document object for the AUDR specification.

3.4.1 JSON Example

{
  "spec_version": "0.5",
  "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": "inference"
  },
  "run": {
    "run_id": "01K4N8B0M2C5F7H9J1L3N6P8QR",
    "name": "Resolve Acme support request",
    "span_id": "model-call-1",
    "run_type": "agent_run"
  },
  "attribution": {
    "environment": "production",
    "account_id": "account-42",
    "user_id": "user-7"
  },
  "usage": {
    "llm": {
      "input_tokens": 1200,
      "output_tokens": 300
    }
  }
}

3.4.2 Field Descriptions

Field NameTypeRequiredDescription
spec_versionstring (pattern)RequiredAUDR schema version, constrained here to 0.5.x. Consumers MUST reject unsupported major versions and, before 1.0, unsupported minor versions.
record_idstring (8–64 chars)RequiredULID or UUIDv7 idempotency key, unique to each emitted record rather than each logical event. Records from different components use distinct IDs and are merged, not deduplicated.
correctsstring (8–64 chars)OptionalIdentifies one earlier record fully restated by this correction. The correction MUST contain full state, use a fresh record_id, and come from the same emitter.component; all-zero usage represents a void.
emitterEmitter ObjectRequiredIdentifies the software component that wrote the record.
timingTiming ObjectRequiredEvent completion, ingest, and duration observations.
resourceResource ObjectRequiredIdentifies the consumed model or tool. Model operations require type=model; tool_execution and retrieval require type=tool.
runRun ObjectRequiredGroups metered operations into a task and span hierarchy. Spawned agents reuse run_id, parent_span_id links within that run, and a harness outcome closes the run.
attributionAttribution ObjectRequiredCarries billability and allocation dimensions. Emitters MUST supply environment; sinks ignore records missing it, and production records require account_id.
usageUsage ObjectRequiredRaw, non-monetary counters with exactly one non-empty llm or tool block selected by resource.operation. An absent counter means unreported or inapplicable; zero means measured as zero and MUST NOT be inferred from absence.
costCost ObjectOptionalProvider- or router-asserted cost that rating MAY use or ignore according to its billing configuration. Components are gross, total_cost is net, and the single cost sub-block must match usage; rating MAY check consistency but MUST NOT overwrite the total.

3.5 Record Identity

The REQUIRED spec_version and record_id properties declare schema version and record identity. The OPTIONAL corrects property identifies the earlier record fully restated by a correction.

3.5.1 JSON Example

{"spec_version": "0.5", "record_id": "01K4N8D2J4P7Q9R3S6T8V1W5XY"}

3.5.2 Field Descriptions

Field NameTypeRequiredDescription
spec_versionstring (pattern)RequiredAUDR schema version, constrained here to 0.5.x. Consumers MUST reject unsupported major versions and, before 1.0, unsupported minor versions.
record_idstring (8–64 chars)RequiredULID or UUIDv7 idempotency key, unique to each emitted record rather than each logical event. Records from different components use distinct IDs and are merged, not deduplicated.
correctsstring (8–64 chars)OptionalIdentifies one earlier record fully restated by this correction. The correction MUST contain full state, use a fresh record_id, and come from the same emitter.component; all-zero usage represents a void.

3.6 emitter Object

The REQUIRED emitter object identifies the software component that wrote the record.

3.6.1 JSON Example

{"component": "router", "name": "@audr/openrouter", "version": "0.5.1"}

3.6.2 Field Descriptions

Field NameTypeRequiredDescription
emitter.componentenum (`harness`, `router`, `provider`, `sdk`, `sink`)RequiredComponent that wrote the record. It distinguishes caller-executed from provider-executed tool usage and cost.
emitter.namestring (min 1 chars)RequiredPackage identifier for the emitter.
emitter.versionstring (min 1 chars)RequiredEmitter release used to attribute data-quality issues.

3.7 timing Object

The REQUIRED timing object records event completion and optional ingest and duration observations.

3.7.1 JSON Example

{"event_time": "2026-09-08T12:00:00.000Z", "duration_ms": 842}

3.7.2 Field Descriptions

Field NameTypeRequiredDescription
timing.event_timestring (date-time)RequiredCompletion time in RFC 3339 format with millisecond precision; for streams, use stream termination. Each emitted record carries its own observation; merged observations are never averaged.
timing.received_timestring (date-time)OptionalIngest time in RFC 3339 format with millisecond precision. Emitters MUST NOT set it; the sink overwrites any supplied value and uses it for lateness and watermark logic.
timing.duration_msinteger ≥ 0OptionalNon-negative call wall-clock duration in milliseconds, used for anomaly detection rather than billing.

3.8 resource Object

The REQUIRED resource object identifies the consumed model or tool and the operation performed.

3.8.1 JSON Example

{"provider": "anthropic", "type": "model", "name": "claude-sonnet-4-20250514", "operation": "inference", "region": "us-east-1", "deployment": "AWS"}

3.8.2 Field Descriptions

Field NameTypeRequiredDescription
resource.providerstring (pattern)RequiredCanonical lowercase provider slug. For tool operations, identify the executing vendor or platform; use self-hosted for locally run tools.
resource.typeenum (`model`, `tool`)RequiredNamed resource kind: model for model operations or tool for tool_execution and retrieval. resource.operation selects the usage block.
resource.namestring (min 1 chars)RequiredVerbatim provider model identifier for models, or stable logical tool/backend identifier for tools. Do not normalize model names or use URLs and versioned function symbols for tools.
resource.operationenum (`inference`, `embedding`, `rerank`, `image`, `audio`, `fine_tune`, `tool_execution`, `retrieval`)RequiredOperation class that selects resource.type and usage: model operations use model with usage.llm; tool_execution and retrieval use tool with usage.tool.
resource.key_namestringOptionalCredential label from the gateway registry. It MUST contain no key material, prefix, hash, or other secret substring.
resource.regionstringOptionalRegion affecting price and data residency.
resource.deploymentstring (min 1 chars)OptionalOpen-vocabulary deployment platform or environment, such as AWS, GCP, Azure, or self-hosted.

3.9 run Object

The REQUIRED run object associates one metered operation with a run and span hierarchy.

3.9.1 JSON Example

{"run_id": "01K4N8B0M2C5F7H9J1L3N6P8QR", "name": "Resolve Acme support request", "span_id": "tool-call-2", "parent_span_id": "model-call-1", "step": 2, "run_type": "agent_run"}

3.9.2 Field Descriptions

Field NameTypeRequiredDescription
run.run_idstring (8–64 chars)RequiredUnique run identifier, generated by the harness or by the router when no harness exists. It MUST be account-unique and identical on every record in the run, including spawned-agent records.
run.namestring (min 1 chars)OptionalOptional human-readable name of the agentic run. When absent, run_id is used in its place for display purposes.
run.span_idstring (min 1 chars)RequiredSpan identifier for one metered operation, unique within run_id. Together they form the sink merge key, which MUST NOT be shared by different operations.
run.parent_span_idstring (min 1 chars)OptionalLinks nested tools and spawned agents to a span in the same run_id. Spawned agents MUST reuse the parent run_id and set this field to their spawning span.
run.stepinteger ≥ 0OptionalOrdinal position within the run.
run.trace_idstringOptionalW3C trace identifier for OpenTelemetry correlation.
run.run_typeenum (`agent_run`, `workflow`, `single_call`)OptionalOverall work shape.
run.error_codestring (min 1 chars)OptionalError code when the run fails. Report consumed usage even on failure; downstream rating decides billability.
run.error_reasonstring (max 32 chars)OptionalHuman-readable message of the run failure, limited to 32 characters.
run.outcomeenum (`resolved`, `escalated`, `abandoned`, `failed`)OptionalThe agent run's final outcome, emitted only by the harness.

3.10 attribution Object

The REQUIRED business attribution object carries environment, user, account, subscription, and label dimensions.

3.10.1 JSON Example

{"environment": "production", "user_id": "user-7", "account_id": "account-42", "subscription_id": "subscription-9", "labels": {"team": "platform"}}

3.10.2 Field Descriptions

Field NameTypeRequiredDescription
attribution.environmentenum (`production`, `staging`, `development`, `test`, `evaluation`)ConditionalDeployment environment. A conformant emitter MUST populate it; a missing value triggers default-deny ignore.
attribution.user_idstringOptionalPseudonymous identity of the triggering user; never an email or name. It MUST NOT be used by rating; account_id MUST be used for rating.
attribution.account_idstring (min 1 chars)ConditionalThe account that pays the bill. Rating may aggregate usage by this account. Required for production traffic; optional otherwise.
attribution.subscription_idstringOptionalSubscription of the paying account for this usage record is associated with.
attribution.labelsobject (≤ 20 key-value pairs)OptionalUp to 20 free-form dimensions for non-billable metadata. Labels MUST NOT contain PII.

3.11 usage Object

The REQUIRED usage object contains raw, non-monetary counters. Exactly one non-empty sub-object MUST be present: llm for model operations or tool for tool execution and retrieval.

3.11.1 JSON Example

{"llm": {"input_tokens": 1200, "output_tokens": 300, "requests": 1}}

3.11.2 Field Descriptions

Field NameTypeRequiredDescription
usage.llmobjectConditionalNon-empty model-call counters. A harness may emit counters read from the provider response.
usage.toolobjectConditionalNon-empty counters reported by the component that executed the tool: harness for caller-held contracts, router for provider-executed tools.

3.11.3 usage.llm Field Descriptions

Field NameTypeRequiredDescription
usage.llm.input_tokensinteger ≥ 0OptionalUncached input tokens; MUST exclude cache reads.
usage.llm.output_tokensinteger ≥ 0OptionalOutput tokens; exclude reasoning tokens when reasoning_tokens is present.
usage.llm.cache_read_tokensinteger ≥ 0OptionalPrompt-cache read tokens, reported separately for distinct pricing.
usage.llm.cache_write_tokensinteger ≥ 0OptionalTokens written to a prompt cache by this call.
usage.llm.reasoning_tokensinteger ≥ 0OptionalReasoning tokens, separate from output for independent pricing.
usage.llm.requestsinteger ≥ 0OptionalRequest count for per-request pricing. No default applies: absent means unreported, while one request is encoded as 1.
usage.llm.images_processedinteger ≥ 0OptionalImages supplied in model input.
usage.llm.audio_input_secondsnumber ≥ 0OptionalSeconds of audio submitted.
usage.llm.audio_output_secondsnumber ≥ 0OptionalSeconds of audio generated.
usage.llm.x_*integer | numberOptionalNon-negative provider counter named x_<provider>_<name>.

3.11.4 usage.tool Field Descriptions

{"tool": {"type": "code_execution", "call_count": 1, "sandbox_time": 4250}}
Field NameTypeRequiredDescription
usage.tool.typestring (min 1 chars)OptionalThe tool operation being metered, such as invocation, api, web_search, code_execution, or retrieval. It complements resource.operation and resource.name.
usage.tool.call_countinteger ≥ 0OptionalInvocation or run count used for per-call pricing. For retrieval, this is usually the query count.
usage.tool.sandbox_timenumber ≥ 0OptionalSandbox compute wall-clock time in milliseconds, distinct from whole-operation timing.duration_ms. Used when an agent run spins up a sandbox for tool execution.
usage.tool.x_*integer | numberOptionalNon-negative implementation counter named x_<name>.

3.12 cost Object

The OPTIONAL cost object records an asserted event cost. When present, it MUST contain total_cost and currency. A rating component MAY use or ignore this assertion according to its own billing configuration.

3.12.1 JSON Example

{"total_cost": 0.0084, "currency": "USD", "llm": {"total_token_cost": 0.0084, "input_token_cost": 0.0036, "output_token_cost": 0.0048}}

3.12.2 Field Descriptions

Field NameTypeRequiredDescription
cost.total_costnumber ≥ 0RequiredEvent-level total cost after discounts.
cost.currencystring (pattern)RequiredCurrency code of the costs in uppercase according to ISO 4217 format.
cost.original_costnumber ≥ 0OptionalList cost before commitments, negotiated rates, or promotions.
cost.discount_amountnumber ≥ 0OptionalDifference between original_cost and total_cost.
cost.discount_percentnumber ≥ 0 ≤ 100OptionalAny provider promotional discount percentage.
cost.llmobjectConditionalThe gross cost of the model operation calls. The breakdown is similar to usage.llm and is present only for model operations.
cost.toolobjectConditionalThe gross cost of the tool execution calls. The breakdown is similar to usage.tool and is present only for tool_execution and retrieval.

3.12.3 cost.llm Field Descriptions

Field NameTypeRequiredDescription
cost.llm.total_token_costnumber ≥ 0RequiredTotal token cost this model call event. Reference only and MAY have rounding differences with the some of individual token costs.
cost.llm.input_token_costnumber ≥ 0OptionalCost of uncached input tokens. This would the total input token cost if cache_read_cost were absent.
cost.llm.output_token_costnumber ≥ 0OptionalOutput token cost and MUST exclude reasoning_cost.
cost.llm.cache_read_costnumber ≥ 0OptionalPrompt-cache read cost.
cost.llm.cache_write_costnumber ≥ 0OptionalPrompt-cache write cost.
cost.llm.reasoning_costnumber ≥ 0OptionalReasoning-token cost.

3.12.4 cost.tool Field Descriptions

{"total_cost": 0.012, "currency": "USD", "tool": {"type": "code_execution", "call_cost": 0.002, "sandbox_cost": 0.01}}
Field NameTypeRequiredDescription
cost.tool.typestring (min 1 chars)OptionalThe tool operation being metered. It SHOULD match usage.tool.type on the same record.
cost.tool.call_costnumber ≥ 0OptionalPer-invocation charge corresponding to usage.tool.call_count.
cost.tool.sandbox_costnumber ≥ 0OptionalCharge corresponding to usage.tool.sandbox_time.
cost.tool.x_*number ≥ 0OptionalCharge amount for an implementation-specific field named x_<name>.

3.13 Cross-Field Operation Constraints

resource.operation determines the required resource.type , usage and cost sub-objects.

Operation classresource.typeusagecost
Model operationsmodelusage.llm present; usage.tool absentcost.llm MAY be present; cost.tool absent
Tool operationstoolusage.tool present; usage.llm absentcost.tool MAY be present; cost.llm absent

3.13.1 JSON Examples

{
  "resource": {"provider": "anthropic", "type": "model", "name": "claude-sonnet-4-20250514", "operation": "inference"},
  "usage": {"llm": {"requests": 1}}
}
{
  "resource": {"provider": "self-hosted", "type": "tool", "name": "search_tickets", "operation": "retrieval"},
  "usage": {"tool": {"type": "retrieval", "call_count": 1}}
}