Cost Explorer can now split Amazon Bedrock spend by provider, model, inference type and feature, which means a Bedrock cost per model view is a one-afternoon job instead of a data engineering project. In this walkthrough you will confirm the new attributes, pull per-model and per-token-type numbers from the CLI, save a report for finance, and put budget and anomaly alerts on top. Everything here uses native Cost Explorer, Budgets and Cost Anomaly Detection.
Prerequisites
- AWS CLI v2 configured against your management or payer account (or a member account with Cost Explorer enabled).
- IAM permissions for
ce:GetDimensionValues,ce:GetCostAndUsage,ce:CreateAnomalyMonitor, Budgets and SNS. - Some Bedrock usage since 2026-09-01 UTC. Product attribute data does not exist before that date, and the API will tell you so.
- A skim of the Cost Explorer user guide if you have never opened it.
- Awareness that each Cost Explorer API request is billed; see cost management pricing. The handful of calls below is pocket change, but do not loop them.
Build your Bedrock cost per model view, step by step
Confirm the attribute keys and model values. The new dimension isPRODUCT_ATTRIBUTE, with keysprovider,model,inferenceTypeandfeature. List the keys first, then the model values, and copy one model value for later steps. The API is documented in GetDimensionValues.aws ce get-dimension-values \
--time-period Start=2026-09-01,End=2026-10-13 \
--dimension PRODUCT_ATTRIBUTE \
--context COST_AND_USAGE
aws ce get-dimension-values \
--time-period Start=2026-09-01,End=2026-10-13 \
--dimension PRODUCT_ATTRIBUTE \
--dimension-key model \
--context COST_AND_USAGE
Pull monthly spend by model. Group by themodelkey. Do not add a SERVICE filter here: Anthropic and OpenAI models bill under their own “(Amazon Bedrock Edition)” service names, and filtering on “Amazon Bedrock” alone would hide them. The--queryflattens the response into a two-column table of model and dollars, which is the first thing anyone will ask you for. Expect a couple of models to dominate; that concentration is normal and is exactly what the budget in step 6 will guard.aws ce get-cost-and-usage \
--time-period Start=2026-09-01,End=2026-10-13 \
--granularity MONTHLY \
--metrics UnblendedCost \
--group-by Type=PRODUCT_ATTRIBUTE,Key=model \
--query 'ResultsByTime[].Groups[].[Keys[0],Metrics.UnblendedCost.Amount]' \
--output table
Break one model down by inference type, daily. Save a filter for the model you copied in step 1, then group byinferenceType. You will see input, output, “global” variants, and prompt cache read and write tokens as separate lines. If cache reads are near zero on a workload with a big repeated system prompt, prompt caching is your next ticket.cat > model-filter.json <<'EOF'
{"ProductAttributes":{"Key":"model","Values":["PASTE_MODEL_VALUE_FROM_STEP_1"]}}
EOF
aws ce get-cost-and-usage \
--time-period Start=2026-10-01,End=2026-10-13 \
--granularity DAILY \
--metrics UnblendedCost UsageQuantity \
--group-by Type=PRODUCT_ATTRIBUTE,Key=inferenceType \
--filter file://model-filter.json
Catch the cost with no provider. Amazon Nova and the olderxai.grok-4.6currently report an empty provider. TheABSENTmatch option shows that bucket so your provider totals reconcile. Add the ABSENT total to your per-provider sums and you should land on the same number as step 2. If you do not, something new has shipped with odd labels, and you just found it before the monthly review did.aws ce get-cost-and-usage \
--time-period Start=2026-09-01,End=2026-10-13 \
--granularity MONTHLY \
--metrics UnblendedCost \
--group-by Type=PRODUCT_ATTRIBUTE,Key=model \
--filter '{"ProductAttributes":{"Key":"provider","MatchOptions":["ABSENT"]}}'
Save a Cost Explorer report for finance. The CLI is for you; the console report is for everyone else. Build it once and share the link.Billing and Cost Management console
-> Cost Explorer
-> Date range: 2026-09-01 to today, Granularity: Monthly
-> Group by: Product attribute -> Model
-> (optional) Filters: Product attribute -> Provider
-> Save to report library -> "Bedrock cost per model"

Create a budget scoped to a provider or model. Budgets picked up the same product attributes at launch. Use the console here; the filter JSON for budgets is new enough that clicking is safer than guessing. The Budgets guide covers the general flow.Billing and Cost Management console
-> Budgets -> Create budget
-> Customize (advanced) -> Cost budget
-> Period: Monthly, Budget renewal: Recurring
-> Budget scope: Filter specific AWS cost dimensions
Product attribute -> Provider (or Model) -> pick value
-> Name: bedrock-anthropic-monthly
-> Set amount from the step 2 numbers plus headroom
Wire budget alerts to an SNS topic. Create the topic and allow the Budgets service to publish to it, then attach it in the budget’s alert thresholds (for example, 80 percent actual and 100 percent forecasted).aws sns create-topic --name bedrock-cost-alerts
aws sns subscribe \
--topic-arn arn:aws:sns:us-east-1:111122223333:bedrock-cost-alerts \
--protocol email \
--notification-endpoint finops@example.com
cat > topic-policy.json <<'EOF'
{"Version":"2012-10-17","Statement":[{"Effect":"Allow",
"Principal":{"Service":"budgets.amazonaws.com"},
"Action":"SNS:Publish",
"Resource":"arn:aws:sns:us-east-1:111122223333:bedrock-cost-alerts"}]}
EOF
aws sns set-topic-attributes \
--topic-arn arn:aws:sns:us-east-1:111122223333:bedrock-cost-alerts \
--attribute-name Policy \
--attribute-value file://topic-policy.json
Add a Cost Anomaly Detection monitor. Budgets watch a number you chose; Cost Anomaly Detection watches for patterns you did not predict. A dimensional SERVICE monitor evaluates each service separately, which covers Amazon Bedrock and every “(Amazon Bedrock Edition)” service. Then attach an alert subscription to the same SNS topic in the console (Cost Anomaly Detection, Alert subscriptions, Create subscription).aws ce create-anomaly-monitor \
--anomaly-monitor '{"MonitorName":"services-incl-bedrock","MonitorType":"DIMENSIONAL","MonitorDimension":"SERVICE"}'
Verify after a day of usage. Cost data lands with a delay, so come back tomorrow and rerun a daily query. New rows by model and inference type mean the pipeline is alive; check the budget page for current and forecasted values too.aws ce get-cost-and-usage \
--time-period Start=2026-10-12,End=2026-10-14 \
--granularity DAILY \
--metrics UnblendedCost \
--group-by Type=PRODUCT_ATTRIBUTE,Key=model
aws ce get-anomaly-monitors \
--query 'AnomalyMonitors[].[MonitorName,MonitorType,MonitorDimension]'
What you built
You now have a Bedrock cost per model view from the CLI, a saved Cost Explorer report the finance team can open without asking you, a per-provider or per-model budget with SNS alerts, and an anomaly monitor watching every Bedrock-related service. You also have a reconciliation habit: the ABSENT query catches the Nova and legacy Grok spend that provider filters miss. Compare what you see against the published rates on the Bedrock pricing page when a number looks off.
Cleanup is easy if this was a trial run: delete the budget in the Budgets console, delete the anomaly subscription and monitor (aws ce delete-anomaly-monitor --monitor-arn ...), and remove the topic with aws sns delete-topic --topic-arn .... The saved report costs nothing to keep. Next stop, if you want to go further: the Classmethod deep dive on the API quirks, especially the SERVICE filter rules for GetDimensionValues.
At Enkompass (enkompass.net), this is our home turf. We set up per-model Bedrock reports, budgets and anomaly alerts for teams whose AI line item outgrew the single-number era. 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.
