v0.1.1Latest · also at /spec/v0.1.1 · GitHub

Open Agent Spend Attribution (OASA) Specification

Version 0.1.1 · Published 2026-09-14 · Revised 2026-09-15 · CC BY 4.0

Abstract

OASA defines a canonical record format for agent spend attribution: attributing AI-agent resource consumption and spend to agent identity, task, and cost object, and joining runtime telemetry, normalized billing, and payment settlement into a single auditable ledger — a system of record for agent spend. It is designed to interoperate with OpenTelemetry GenAI semantic conventions (telemetry), the FOCUS specification (billing), and x402 payment-rail records (settlement). It is not a payment protocol and not a billing format; it is the join between settlement, billing, and attribution.

Partial records are valid. Every field outside the envelope is optional so adapters can emit what they know and reconcile later. Within a major version, the schema is additive-only.

Design principles

  • Hub-and-spoke: canonical middle, adapters at the edges.
  • Settlement-agnostic: invoice, card, wire, and on-chain rails reconcile into the same spine.
  • Additive to FOCUS and OpenTelemetry — never competing with them.
  • Envelope required; all other groups optional so partial records remain valid.
  • Versioned; additive-only within a major version.

The three-layer model

TelemetryOTel GenAIAttributionOASA (canonical)BillingFOCUS+ Settlement (x402)trace_idinvoice_id + source_record_idsettlement_refHub-and-spoke: one canonical middle, adapters at the edges
Join keys on the edges; attribution in the middle.

Record schema v0.1.1

Group 1 — Envelope (required)

FieldTypeRequiredDescription
record_idstring (UUIDv7)YesGlobally unique record identifier.
record_typeenum: usage | charge | settlement | allocation | outcomeYesOne row = one event class.
schema_versionstringYesSchema version string; "0.1" for this draft.
occurred_attimestamp (RFC 3339, UTC)YesWhen the event happened.
recorded_attimestamp (RFC 3339, UTC)YesWhen the record was ingested.
source_systemstringYese.g. otel-collector, openai-billing, x402-facilitator.
source_record_idstringYesKey in the source system.
currencystringYesISO 4217, or CAIP-19 asset ID for on-chain assets.

Group 2 — Agent identity

FieldTypeRequiredDescription
agent_idstringNoStable internal agent ID.
agent_namestringNoHuman-readable agent name.
agent_versionstringNoAgent build or prompt version.
agent_ownerstringNoTeam or principal accountable.
parent_agent_idstringNoParent in a sub-agent chain.
agent_frameworkstringNoe.g. langgraph, crewai, custom.
identity_schemeenum: internal | erc8004 | otherNoHow external identity is named.
external_identity_refstringNoe.g. ERC-8004 registration reference.

Group 3 — Task & session context

FieldTypeRequiredDescription
session_idstringNoRuntime session identifier.
trace_idstringNoW3C Trace Context / OpenTelemetry trace id.
span_idstringNoSpan id within the trace.
task_idstringNoOrg-defined task identifier.
task_typestringNoFree taxonomy; org-defined.
workflow_idstringNoWorkflow or pipeline id.
triggerenum: human | scheduled | agent | eventNoWhat started the run.
initiating_principalstringNoHuman or agent that authorized the run.

Group 4 — Consumption

FieldTypeRequiredDescription
providerstringNoModel or API provider.
servicestringNoService product name.
modelstringNoModel identifier.
operationenum: chat | completion | embeddings | tool_call | inference | storage | api_call | otherNoOperation class.
input_tokensintegerNoInput token count.
output_tokensintegerNoOutput token count.
cached_tokensintegerNoCached / reused tokens when reported.
reasoning_tokensintegerNoReasoning tokens when reported.
unit_typeenum: tokens | requests | seconds | gb | customNoUnit of consumption.
units_consumeddecimalNoQuantity in unit_type.
tool_namestringNoTool invoked, if any.
request_countintegerNoRequest count for the event.

Group 5 — Cost

FieldTypeRequiredDescription
list_costdecimalNoList price; mirrors FOCUS ListCost semantics.
billed_costdecimalNoBilled amount; mirrors FOCUS BilledCost.
effective_costdecimalNoEffective cost after discounts; mirrors FOCUS EffectiveCost.
cost_sourceenum: measured | rated | invoicedNoHow cost was derived.
pricing_refstringNoPrice-sheet row ID.
invoice_idstringNoVendor invoice identifier.
focus_charge_refstringNoPointer into a FOCUS dataset row.

Group 6 — Allocation

FieldTypeRequiredDescription
cost_centerstringNoCost center or department.
project_idstringNoProject identifier.
customer_idstringNoCustomer or account identifier.
product_linestringNoProduct line.
environmentenum: prod | staging | dev | otherNoRuntime environment.
tagsmap<string,string>NoFree-form tags.
allocation_methodenum: direct | rule | splitNoHow cost was allocated.
allocation_rule_idstringNoRule that produced the allocation.
split_fractiondecimal (0–1)NoShare of a split allocation.

Group 7 — Settlement join

FieldTypeRequiredDescription
settlement_railenum: invoice | card | ach | wire | x402 | other_onchainNoHow money moved.
settlement_networkstringNoCAIP-2 chain ID where applicable.
settlement_assetstringNoCAIP-19 asset identifier.
settlement_amountdecimalNoSettled amount.
settlement_refstringNoTx hash, statement line, or remittance ID.
settled_attimestampNoSettlement timestamp.
reconciliation_statusenum: unmatched | matched | partial | disputedNoJoin status against billing/telemetry.

Group 8 — Control & governance

FieldTypeRequiredDescription
budget_idstringNoBudget that constrained or funded the spend.
policy_idstringNoPolicy identifier.
authorization_refstringNoMandate / verifiable-intent credential ID.
approval_typeenum: policy_auto | pre_authorized | human_approvedNoHow spend was authorized.

Group 9 — Outcome (optional, forward-looking)

Outcome capture is intentionally minimal in v0.1; it exists so cost-per-outcome queries have a landing zone.

FieldTypeRequiredDescription
outcome_event_idstringNoLinked outcome event.
outcome_typestringNoOutcome class (org-defined).
outcome_valuedecimalNoNumeric outcome value.
outcome_unitstringNoUnit for outcome_value.
business_metric_refstringNoPointer to a business metric definition.

Mapping tables

Verified against upstream docs on 2026-09-15. OpenTelemetry GenAI conventions are still experimental and may drift; attribute names here are current as of that date, and unmapped OASA fields are noted where no ratified equivalent exists. FOCUS token-economics columns track 1.4 (ratified) and 1.5 (scheduled). x402 V2 communicates requirements via PAYMENT-REQUIRED payloads (network, asset, amount, payTo).

OASA ↔ OpenTelemetry GenAI

OASAOTelNotes
providergen_ai.provider.name
input_tokensgen_ai.usage.input_tokens
output_tokensgen_ai.usage.output_tokens
cached_tokensgen_ai.usage.cache_read.input_tokensCached/reused input tokens. Where a provider reports cache reads separately, map the cache-read count here; do not double-count into input_tokens if the provider already reports them inclusively. OTel also defines gen_ai.usage.cache_creation.input_tokens for cache writes.
reasoning_tokensgen_ai.usage.reasoning.output_tokensOutput tokens used for reasoning (e.g. chain-of-thought). OTel says this value SHOULD be included in gen_ai.usage.output_tokens. Where a provider reports reasoning only in billing payloads, populate from the provider usage object.
modelgen_ai.request.modelThe requested model. Where a provider returns a resolved or versioned model, prefer that value and record the requested model in tags if both matter.
operationgen_ai.operation.name
tool_namegen_ai.tool.nameEmitted on tool-execution spans. Pair with operation = tool_call.
session_idgen_ai.conversation.idWhere a runtime emits a conversation/thread identifier. OASA session_id is broader — a non-conversational agent run is still a session.
agent_idgen_ai.agent.id
agent_namegen_ai.agent.name
trace_id / span_idW3C Trace Context / OTel trace_id, span_idJoin key to the Attribution layer; carried from W3C Trace Context.

OASA ↔ FOCUS

FOCUS, the FinOps Foundation's open billing specification, added token-economics columns in 1.4; FOCUS 1.5 (Dec 2026 target) adds native token tracking and a Price Sheet dataset. OASA tracks those columns as they ratify.

OASAFOCUS
list_costListCost
billed_costBilledCost
effective_costEffectiveCost
providerProviderName
serviceServiceName
tagsTags
charge rows (record_type=charge)ChargeCategory / charge rows

OASA ↔ x402

OASAx402
settlement_networkPaymentRequired.network (PAYMENT-REQUIRED)
settlement_assetPaymentRequired asset / token
settlement_amountPaymentRequired amount / price
settlement_refon-chain tx / SettlementResponse reference
(payee context)PaymentRequired.payTo

Worked example

One agent tool-call as a usage row, later joined by a charge row and an x402 settlement row sharing trace_id / settlement_ref.

1. Usage (telemetry)

{
  "record_id": "0193f0a0-0000-7000-8000-000000000001",
  "record_type": "usage",
  "schema_version": "0.1",
  "occurred_at": "2026-09-01T15:04:05Z",
  "recorded_at": "2026-09-01T15:04:06Z",
  "source_system": "otel-collector",
  "source_record_id": "span-9f2c",
  "currency": "USD",
  "agent_id": "agent-support-47",
  "agent_name": "Support Triage",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "task_type": "ticket_resolve",
  "provider": "openai",
  "model": "gpt-4.1",
  "operation": "tool_call",
  "tool_name": "crm.lookup",
  "input_tokens": 1200,
  "output_tokens": 340,
  "cached_tokens": 800,
  "session_id": "sess-2f91",
  "unit_type": "tokens",
  "units_consumed": 1540,
  "cost_source": "measured"
}

2. Charge (billing)

{
  "record_id": "0193f0a0-0000-7000-8000-000000000002",
  "record_type": "charge",
  "schema_version": "0.1",
  "occurred_at": "2026-09-02T00:00:00Z",
  "recorded_at": "2026-09-02T06:12:00Z",
  "source_system": "openai-billing",
  "source_record_id": "inv_line_88421",
  "currency": "USD",
  "agent_id": "agent-support-47",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "invoice_id": "INV-2026-09-01",
  "focus_charge_ref": "focus:row:88421",
  "list_cost": 0.042,
  "billed_cost": 0.038,
  "effective_cost": 0.038,
  "cost_source": "invoiced"
}

3. Settlement (x402)

{
  "record_id": "0193f0a0-0000-7000-8000-000000000003",
  "record_type": "settlement",
  "schema_version": "0.1",
  "occurred_at": "2026-09-01T15:04:07Z",
  "recorded_at": "2026-09-01T15:04:08Z",
  "source_system": "x402-facilitator",
  "source_record_id": "pay_0xabc…",
  "currency": "eip155:8453/erc20:0x…",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "settlement_rail": "x402",
  "settlement_network": "eip155:8453",
  "settlement_asset": "eip155:8453/erc20:0x…",
  "settlement_amount": 0.038,
  "settlement_ref": "0xdeadbeef…",
  "settled_at": "2026-09-01T15:04:07Z",
  "reconciliation_status": "matched"
}

References

Upstream specifications and standards this document maps to or depends on.

ReferenceStewardLink
OpenTelemetry GenAI semantic conventionsOpenTelemetry (CNCF)opentelemetry.io/docs/specs/semconv/gen-ai/
FOCUS™ (FinOps Open Cost and Usage Specification)FinOps Foundation (Linux Foundation)focus.finops.org/
x402x402 Foundation (Linux Foundation)x402.org/
W3C Trace ContextW3Cwww.w3.org/TR/trace-context/
CAIP-2 (chain ID) / CAIP-19 (asset ID)Chain Agnostic Standards Alliancechainagnostic.org/
ERC-8004 (agent identity)Ethereumeips.ethereum.org/
RFC 3339 (timestamps)IETFwww.rfc-editor.org/rfc/rfc3339
ISO 4217 (currency codes)ISOwww.iso.org/iso-4217-currency-codes.html
UUIDv7 (RFC 9562)IETFwww.rfc-editor.org/rfc/rfc9562

Referencing these specifications does not imply endorsement by their stewards. OASA is an independent publication of Onaro (BrianOnAI LLC).

Changelog

  • v0.1.1 (2026-09-15) — Extended the OpenTelemetry GenAI mapping with tool, cached-token, conversation, and reasoning attributes; added a Notes column. Mapped cached_tokens to gen_ai.usage.cache_read.input_tokens (registry name as of 2026-09-15). No schema fields added, removed, or renamed; schema_version remains "0.1".
  • v0.1 (2026-09-14) — initial public draft.

Contributing

The specification is developed in the open at github.com/onaro-io/agent-spend-attribution. Open an issue for anything wrong, missing, or ambiguous — especially an upstream attribute name that has drifted — or a pull request against SPEC.md for concrete changes. Implementation reports are the most useful contribution: if you have tried to map real agent spend with this schema, what broke is what the next version needs to fix.

General comments: hello@onaro.io

Cite this specification

Open Agent Spend Attribution (OASA) Specification, version 0.1.1 (rev. 2026-09-15). Onaro. https://www.onaro.io/spec

Repository: https://github.com/onaro-io/agent-spend-attribution

License: CC BY 4.0. Attribution required; adaptations allowed.

Related: The Missing Ledger · Agent spend attribution · Agent payment data