Documentation / Attribution / Tagging convention
Tagging convention
The full standard is OASA 0.1.3. The practical guide, with the provider citations behind this page, is Attributing agent spend. This page is the short version, plus what Meridian actually reads.
A tag or label reaches a bill only when the provider copies it onto a cost row. The keys below are the ones to put on that copy. They are lowercase so a Google request label will accept them.
Recommended keys
| Key | Meaning |
|---|---|
oasa_cost_center | The department or other cost center to charge |
oasa_agent | The agent |
oasa_owner | The person who owns the agent |
oasa_project | The project |
environment | Where it ran. Use prod, staging, or dev when it is one of those |
environment is not one of the four attribution fields. It does not, by itself, assign a department.
Rules that make them work
These limits are the Google Cloud request-label rules. They are the strictest of the providers, so a key that passes them is safe to reuse. (Custom metadata labels)
- Keys and values are lowercase letters, digits, underscores, and dashes.
- A key starts with a lowercase letter.
- A key and a value are at most 63 characters.
- Do not use an empty value.
- Keep the number of distinct values small. After 1,000 distinct values for one key over the life of a Google billing account, that key can be dropped without notice. An agent catalog larger than that must not put
oasa_agenton Google labels. Bind those agents from the project id instead.
Do not put a per-request id in a tag or a label. That includes a trace id, a span id, a session id, a task id, a request id, a message id, an end-user id, an email address, or a timestamp. Bedrock's own cost guidance says session ids, trace ids, and experiment ids belong in request metadata, not in cost allocation tags. (Bedrock cost best practices) Request metadata does not reach the bill. A tag with a new value per call will also blow the cardinality limit.
Where to put them
Amazon Bedrock. On the application inference profile, or on a mantle project. One profile is one model, so a workload with several models needs the same keys on each profile. Activate the keys as cost allocation tags. They apply going forward. (Application inference profiles, activating tags)
Azure. On the Foundry resource and on the model deployment. Azure also copies billing, resource-group, and subscription tags onto child usage for the common agreement types. A new tag can take about a day to show on usage. (Foundry costs, tag resources)
Google Vertex AI. On the labels object of a pay-as-you-go generateContent or streamGenerateContent call. For the partner models that page lists, Anthropic and Mistral, send X-Vertex-AI-Labels on rawPredict and streamRawPredict. Provisioned Throughput drops the labels and the call still succeeds. A Google model call holds 64 labels. A listed partner-model call holds 32.
Anthropic and OpenAI APIs. There is no cost-allocation tag. Use a workspace, a project, or a key, then map it. See Anthropic and OpenAI.
Gateways. The key you map is the identity Meridian uses. A tag inside the gateway reaches the provider bill only when the upstream call writes a tag or a label the provider stores. See gateways.
OpenTelemetry. On the span, oasa.agent.id, oasa.cost_center, oasa.agent.owner, and oasa.project.id are the attributes. Those attribute the usage record. They are not on the provider invoice. See OASA events.
What Meridian reads today
Meridian does not read oasa_cost_center unless your FOCUS tag mapping lists it.
On a FOCUS upload the default keys are:
| What it sets | Keys Meridian reads by default |
|---|---|
| Department | CostCenter, Department, cost-center |
| Agent | Agent |
| Project | Project |
| Customer | Customer |
Matching ignores letter case, a user: prefix, and spaces, dashes, and underscores. CostCenter, user:cost-center, and cost_center are the same key. oasa_cost_center is not. It does not match CostCenter. oasa_agent does not match Agent. oasa_owner is not a default key at all. environment is not read as a department.
The Azure OpenAI pull and the Vertex and Gemini pull do not read tags or labels at all. A key you put on those resources changes the cloud bill. It does not change those connectors. The Bedrock Cost Explorer pull is a daily total and does not read tags either. The FOCUS upload is the path that reads the table above.
There is no settings screen for the key list. A saved mapping on the organization can replace each list, including with oasa_cost_center, oasa_agent, oasa_project, and a key you choose for the owner. It can also pin a tag value to a department. Onaro saves that mapping with you. Until it is saved, only the defaults are read.
An agent key still has to match an agent name that already exists. The mapping changes which key is read. It does not create the agent. A cost-center value still has to match a department code or name, unless that value is pinned.
Source identities is a different list. It maps Anthropic workspaces, OpenAI projects and keys, and OASA cost centers. It does not edit FOCUS tag keys.
What stays unattributed
A FOCUS row that has none of the keys in the table, and no account crosswalk, stays unattributed. The inbox says "No cost allocation tags", or "Cost center value not mapped" when a cost-center key was present and the value matched no department. An oasa_cost_center tag, while the default list is still in force, does not count as a cost-center key. The row is unattributed until you add a key Meridian reads, or Onaro saves a mapping that lists oasa_cost_center.
The Azure OpenAI, Vertex, Gemini, and Bedrock Cost Explorer pulls do not read these keys. Their rows stay unattributed until a rule or a person assigns them. Putting the convention keys on the cloud resource does not clear that inbox.