On October 8, AWS shipped Bedrock product attributes in Cost Explorer, and the most annoying question in GenAI FinOps (“which model ate the budget?”) finally has a native answer. No data lake, no export job, just a new dimension called PRODUCT_ATTRIBUTE that splits Bedrock spend by provider, model, inference type and feature. It works well. It also has quirks that will waste your morning if nobody warns you, so consider this the warning.
What actually shipped
The AWS roundup put it plainly: Cost Explorer, Budgets and Dashboards now offer detailed cost analysis for Amazon Bedrock, broken down by model, provider, inference type and feature (see the October roundup). Under the hood, that is one new dimension in the Cost Explorer API with four keys hanging off it. It applies to Amazon Bedrock only, and the data starts on 2026-09-01 UTC. Ask for anything earlier and the API refuses with “Product attribute information is not available before 2026-09-01.”
If you already did the heavy lifting last week with IAM-principal allocation and CUR queries, keep it; this is the lightweight layer that sits on top, right inside Cost Explorer.
The four keys of Bedrock product attributes
The folks at Classmethod poked at the new dimension right after launch and confirmed the keys and the values you will actually see:
- provider: Anthropic, OpenAI, xAI, and an empty value (more on that empty value below).
- model: the individual model, which is the key you will group by ninety percent of the time.
- inferenceType: Input tokens, Output tokens, “global” variants of both for cross-Region global inference, plus Prompt cache read input tokens and Prompt cache write input tokens.
- feature: for example On-demand Inference.
That inferenceType key is the sleeper hit. Cache reads and cache writes show up as their own lines, so you can finally see whether prompt caching is paying for itself instead of guessing from latency graphs.
Why Claude lives under a different service name
Here is the first trap. Anthropic and OpenAI models are billed under their own SERVICE names, each ending in “(Amazon Bedrock Edition)”. Grok 4.7 and the Amazon Nova family sit under the plain “Amazon Bedrock” service. If you filter Cost Explorer on SERVICE = Amazon Bedrock and call it a day, your Claude and GPT spend quietly vanishes from the report.
The new dimension papers over that split: group by provider and Claude lands under Anthropic regardless of which SERVICE row it was billed to. Typing “bedrock” into the SERVICE filter, by the way, returns roughly 32 services, including non-model ones like AgentCore. Nice catalog, terrible filter.
Start by asking the API what it knows. The first call lists the keys; the second lists values for one key.
# Which product attribute keys exist in this window?
aws ce get-dimension-values \
--time-period Start=2026-09-01,End=2026-10-09 \
--dimension PRODUCT_ATTRIBUTE \
--context COST_AND_USAGE
# Which providers have spend?
aws ce get-dimension-values \
--time-period Start=2026-09-01,End=2026-10-09 \
--dimension PRODUCT_ATTRIBUTE \
--dimension-key provider \
--context COST_AND_USAGE
The full parameter reference lives in the GetDimensionValues API docs.

Grouping and filtering with get-cost-and-usage
Once you know the values, the useful query is a monthly roll-up grouped by model. PRODUCT_ATTRIBUTE works as a group-by type, just like DIMENSION or TAG:
aws ce get-cost-and-usage \
--time-period Start=2026-09-01,End=2026-10-10 \
--granularity MONTHLY \
--metrics UnblendedCost \
--group-by Type=PRODUCT_ATTRIBUTE,Key=model
To narrow to third-party providers, filter with the new ProductAttributes expression. It behaves like the familiar Dimensions and Tags blocks in the GetCostAndUsage filter grammar:
aws ce get-cost-and-usage \
--time-period Start=2026-09-01,End=2026-10-10 \
--granularity MONTHLY \
--metrics UnblendedCost \
--group-by Type=PRODUCT_ATTRIBUTE,Key=model \
--filter '{"ProductAttributes":{"Key":"provider","Values":["Anthropic","OpenAI","xAI"]}}'
The ABSENT bucket you must not ignore
Not every line item carries every attribute. Nova and the older xai.grok-4.6 come back with an EMPTY provider, so a provider filter like the one above silently drops them. The fix is the ABSENT match option, which returns the cost that has no value for a key:
aws ce get-cost-and-usage \
--time-period Start=2026-09-01,End=2026-10-10 \
--granularity MONTHLY \
--metrics UnblendedCost \
--group-by Type=PRODUCT_ATTRIBUTE,Key=model \
--filter '{"ProductAttributes":{"Key":"provider","MatchOptions":["ABSENT"]}}'
Run this once a week. If the ABSENT total is not trivial, your “spend by provider” chart is lying by omission, and you want to know before finance does.
SERVICE filter rules, per API
This is the quirk most likely to produce a confusing ValidationException. The rules differ by API:
- GetCostAndUsage: a SERVICE filter is optional when you use ProductAttributes. Filter on the attribute alone and it works.
- GetDimensionValues, GetTags, GetCostCategories: when ProductAttributes appears in the filter, a SERVICE filter is required alongside it, combined with an
And.
So the same filter JSON that works in your cost report fails when you reuse it to populate a dropdown of tag values. Not a bug you can fix, just a rule to encode in your helper functions. And remember the service-name split: if you need a SERVICE filter, list the “(Amazon Bedrock Edition)” services as well as Amazon Bedrock itself.
Gotchas worth writing on a sticky note
- September 1 is a hard floor. Month-over-month comparisons against August are impossible here. Your first clean quarter-over-quarter view arrives in 2027.
- Empty providers are real. Group by
modelfor completeness, byproviderfor strategy, and reconcile with the ABSENT bucket. - “global” inference types are separate rows. Global cross-Region inference tokens do not merge with regional ones, which is useful for comparing the two and annoying for a single “input tokens” total.
- Service names drift. New model families can arrive with new SERVICE names. Hard-coded SERVICE lists rot; grouping by the attribute keys does not.
- It is Bedrock only. SageMaker endpoints and self-hosted models do not get this treatment.
- API calls cost money. Programmatic Cost Explorer requests are billed per request; check the cost management pricing page before you put a query in a tight loop.
Per-token rates themselves are on the Bedrock pricing page. Put the two side by side and you can sanity-check whether a model’s line in Cost Explorer matches the token volume you think you sent. When it does not, you usually find a runaway retry loop, an uncached system prompt or a dev environment someone forgot about.
Where this fits in your FinOps stack
Treat Bedrock product attributes as the default lens for model-level questions: which model, which provider, cached or not, global or regional. Keep heavier tooling for per-team chargeback and token-level forensics. Most teams will find that this one dimension answers the weekly “why did the AI line go up” question in under a minute, which is more than the old approach of squinting at a single Bedrock total ever managed.
At Enkompass (enkompass.net), this is our home turf. We build per-model Bedrock cost reporting for teams running Claude, GPT and Nova side by side, including the ABSENT-bucket reconciliation that keeps the numbers honest. If you’d rather have seasoned cloud people handle it instead of learning the hard way at 2 AM, let’s talk. Reach out through our contact page or call us directly at +1-828-436-5667 — we’ll help you turn this from a someday-project into a done-deal.
