Track Spend by Tag
Cost-allocation tags reuse the key/value tags you already set on an agent and give them a second job: attributing LLM spend. Tag your agents with a dimension that matches how you report cost (for example, department, team, or env), and the Agentic Data Plane attributes every LLM call that agent makes to those tags. You can then break spend down by department on the Cost and usage page, or use the API, which also filters by tag, to pull per-team totals for chargeback.
You configure no separate tag registry and no spending pipeline. Tag an agent, and its spend is attributed automatically from the next call onward.
After reading this page, you will be able to:
-
Tag agents so their LLM spend is attributed to a department, team, or environment
-
Group spend by tag on the Cost and usage page
-
Query spend by tag programmatically through SpendingService
Prerequisites
-
A running agent. If you do not have one, see Agentic Data Plane Quickstart for Administrators.
-
To query spend through the API, a service account with the
dataplane_adp_spending_getpermission. See Spending permissions.
How tag-based spend tracking works
When an agent makes an LLM call through AI Gateway, the Agentic Data Plane records a spending event and stamps it with a snapshot of that agent’s tags at the time of the call. Cost reports then group and filter on those stamped tags.
Three behaviors follow from this design:
- Attribution is point-in-time and immutable
-
The tags recorded on a spending event are the agent’s tags at the moment of the call. Editing an agent’s tags later never rewrites past spend: historical rows keep the tags they were recorded with, and new spend picks up the new tags. A chargeback report for a closed period stays stable even after you retag agents.
- Tag changes take a short time to take effect
-
After you create or retag an agent, its spend can briefly record under the old tags, or as untagged, until the change takes effect.
- Unattributable spend is grouped as Untagged
-
Calls that carry no value for the tag key you group on collapse into a single Untagged row. This bucket covers direct user calls that do not run through an agent, calls from an agent that has no tags, and the brief window before a new agent’s tags take effect.
Tag your agents for cost tracking
Tags live on the agent. Set them when you create an agent or edit an existing one, either in the agent form (the Tags section) or through the CreateAgent and UpdateAgent methods. See Create an Agent.
A tag is a key/value pair. Choose keys that match your reporting dimensions and apply them consistently across agents:
| Tag | Attributes spend to |
|---|---|
|
A business unit or cost center. |
|
A team within a department. |
|
An environment, to separate production spend from staging or development. |
|
Do not put secrets or personally identifiable information (PII) in tag values. Tag values appear in cost reports and API responses. |
Track spend by tag in the UI
Open Cost and usage in the sidebar. For the page overview, see Analyze Cost and Usage. The Tags tab appears when cost-allocation tags are available for your organization. In the Spend breakdown table, click the Tags tab, then choose a tag key, for example department. Each row becomes one value of that key, plus an Untagged row for spend with no value for it, so you can see how spend splits across departments or environments over the selected range. The key list holds the keys seen on spend in the current window, so a key with no tagged spend in the range doesn’t appear.
Click a row to see its details, including a chart of that tag value’s spend over the window. You can’t chart a tag row against the gateway total in the Resource spend chart, so the Compare trend action doesn’t appear for tag rows.
To export the tag breakdown, open the Export menu and choose Breakdown table as shown (CSV) while the Tags tab is selected. The full report doesn’t group by tag. To filter spend by tag value, or to combine tag keys, use the API. See Query spend by tag with the API.
Query spend by tag with the API
The SpendingService API exposes tags as a breakdown dimension and a filter. These calls use the same authentication, SpendingFilter shape, and dataplane_adp_spending_get permission as the rest of the spending API. For authentication and the base request shape, see Query spend programmatically.
Reach the methods over the Connect protocol (POST and JSON) at <dataplane-base>/redpanda.api.adp.v1alpha1.SpendingService/<Method>. In this path, <dataplane-base> is your environment’s AI Gateway base URL. Request fields use snake_case (start_time, tag_key), and the JSON response uses camelCase (totalCostMicrocents, totalRequests).
Group a breakdown by tag
The GetSpendingBreakdown and GetSpendingTimeSeriesByDimension methods accept BREAKDOWN_DIMENSION_TAG as the dimension, together with a tag_key that names the key to group on:
| Field | Meaning |
|---|---|
|
Set to |
|
The tag key to group on, for example, |
Each entry in the response keys on a tag value, with the same stats object (cost in microcents, request count, and token buckets) as the other breakdown dimensions. Spend with no value for the key is returned under the empty-string key, which the UI labels Untagged.
Filter any query by tag
Every spending query reads a SpendingFilter, which accepts an AIP-160 filter expression. Reference a tag with tags.<key>, where <key> is the tag key to match:
tags.department = "sales"
tags.department = "sales" AND tags.env = "prod"
Tag predicates compose with the structured SpendingFilter fields, such as provider_name, model_id, user_email, and agent_name, so you can scope a per-user breakdown to one department.
cURL example
Break down the last seven days of spend by department:
ACCESS_TOKEN="<oidc-access-token>" # from the client_credentials flow
DATAPLANE_BASE="https://aigw.<cluster-id>.clusters.rdpa.co"
curl -s --request POST \
--url "${DATAPLANE_BASE}/redpanda.api.adp.v1alpha1.SpendingService/GetSpendingBreakdown" \
--header "Authorization: Bearer ${ACCESS_TOKEN}" \
--header 'Content-Type: application/json' \
--data '{
"filter": {
"start_time": "2026-05-17T00:00:00Z",
"end_time": "2026-05-24T00:00:00Z"
},
"dimension": "BREAKDOWN_DIMENSION_TAG",
"tag_key": "department"
}' | jq
In this URL, <cluster-id> is your cluster’s ID, and <oidc-access-token> is a token from the client-credentials flow. The response carries one entries row per department value in the window, plus a row for untagged spend whose key is the empty string (omitted from the JSON). Each row has a key, the tag value, and a stats object whose fields use camelCase JSON names, such as totalCostMicrocents and totalRequests, plus per-bucket token usage. Divide totalCostMicrocents by 100,000,000 to convert to dollars.
Limits and constraints
| Constraint | Value |
|---|---|
Tags per agent |
At most 50 key/value pairs per agent. |
Tag value length |
At most 256 characters per value. |
Distinct tag keys |
No fixed limit. The keys available for grouping are whatever keys exist across agents that have recorded spend in the selected window. |
Untagged spend |
Spend with no value for the grouped key (direct user calls, untagged agents, and spend recorded before an agent’s tags take effect) is grouped under a single Untagged bucket. |
Troubleshooting
- Spend you expect under a tag shows as Untagged
-
The agent had no tags when it made the call, or you tagged or retagged it moments earlier and the change had not taken effect yet. Recheck after a short wait. Direct user calls that do not run through an agent are always untagged.
- Editing an agent’s tags did not change past reports
-
Attribution is point-in-time by design. Only spend recorded after the edit picks up the new tags; historical spend keeps the tags it was recorded with.