AWS Cost Explorer is the primary GUI and API surface for operational Bedrock cost management. It covers 13 months of history plus 18-month forecasting, supports programmatic access via get_cost_and_usage, and integrates with AWS Cost Anomaly Detection. This note covers the filter combinations, API patterns, and operational limits that matter specifically for Bedrock workloads — including the gaps where Cost Explorer falls short and CUR + Athena is the correct tool.
1. Cost Explorer Filter Combinations for Bedrock
Service dimension
The most reliable starting filter. Bedrock charges flow under the service name Amazon Bedrock. In the GUI: Filters → Service → Amazon Bedrock. In the API:
Filter={
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
}
Product code
Bedrock’s product code in CUR line items is AmazonBedrock. In Cost Explorer the SERVICE dimension is functionally equivalent for most queries — the product code dimension is more useful in raw CUR/Athena queries than in Cost Explorer API calls, where SERVICE is the canonical key.
Usage type dimension
Usage types for Bedrock follow the pattern <region-prefix>-<usage>. Examples:
USE1-InputTokens-Claude— Claude input tokens, us-east-1USE1-OutputTokens-Claude— Claude output tokens, us-east-1USE1-CacheWriteInputTokens-Claude— prompt cache write tokensUSE1-CacheReadInputTokens-Claude— prompt cache read tokensUSE1-InputTokens-Llama— Llama input tokens
The region prefix is two to four characters (USE1, USW2, EUW1, APN1, etc.). Usage types are enumerable via GetDimensionValues with Dimension: USAGE_TYPE.
Linked account filter
In an AWS Organization, isolate a specific account’s Bedrock spend:
Filter={
"And": [
{
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
{
"Dimensions": {
"Key": "LINKED_ACCOUNT",
"Values": ["123456789012"],
"MatchOptions": ["EQUALS"]
}
}
]
}
For multi-account reporting, omit the LINKED_ACCOUNT filter and add it as a GroupBy dimension instead (see section 2).
Compound filter pattern — Bedrock by account and token type
import boto3
from datetime import date
ce = boto3.client("ce", region_name="us-east-1")
response = ce.get_cost_and_usage(
TimePeriod={
"Start": "2026-06-01",
"End": "2026-06-18"
},
Granularity="DAILY",
Filter={
"And": [
{
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
{
"Dimensions": {
"Key": "USAGE_TYPE",
"Values": ["USE1-InputTokens", "USE1-OutputTokens"],
"MatchOptions": ["STARTS_WITH"]
}
}
]
},
GroupBy=[
{"Type": "DIMENSION", "Key": "USAGE_TYPE"},
{"Type": "DIMENSION", "Key": "LINKED_ACCOUNT"}
],
Metrics=["BlendedCost", "UsageQuantity"]
)
2. Grouping Dimensions for Bedrock in Cost Explorer
Dimensions that surface actionable signal
| GroupBy key | What it shows | Practical use |
|---|---|---|
SERVICE |
Bedrock vs SageMaker vs Marketplace | Cross-product rollup; baseline |
USAGE_TYPE |
Model + token type + region | Per-model cost breakdown |
LINKED_ACCOUNT |
Per-team or per-env account | Chargeback / showback |
TAG |
Custom cost allocation tags | Application, team, project |
OPERATION |
InvokeModel, Converse, InvokeModelWithResponseStream |
API surface breakdown |
REGION |
us-east-1, eu-west-1, etc. | Cross-region inference overhead |
Most useful two-dimension grouping
USAGE_TYPE + LINKED_ACCOUNT gives the most actionable dashboard view for a multi-account organization: you see per-model spend per account without any tag setup overhead.
TAG grouping unlocks organizational taxonomy (department, product, environment) but requires:
- Application inference profiles configured per workload
- Cost allocation tags activated in the Billing console
- Up to 24-hour propagation lag before tags appear in Cost Explorer
OPERATION dimension for Bedrock
InvokeModel and Converse are the primary operation values. InvokeModelWithResponseStream is present in CUR but may not be available as a distinct grouping key in all Cost Explorer API versions — validate with GetDimensionValues before building reports that depend on it.
3. get_cost_and_usage API — Bedrock Filter Reference
Full programmatic example: daily spend by model and account
import boto3
import json
from datetime import date, timedelta
def bedrock_daily_cost_by_model_account(start: str, end: str) -> dict:
"""
Return daily Bedrock costs grouped by usage type (model + token type)
and linked account. Covers input, output, and cache tokens.
"""
ce = boto3.client("ce", region_name="us-east-1")
response = ce.get_cost_and_usage(
TimePeriod={"Start": start, "End": end},
Granularity="DAILY",
Filter={
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
GroupBy=[
{"Type": "DIMENSION", "Key": "USAGE_TYPE"},
{"Type": "DIMENSION", "Key": "LINKED_ACCOUNT"}
],
Metrics=["UnblendedCost", "UsageQuantity"]
)
return response["ResultsByTime"]
def bedrock_cost_by_tag(tag_key: str, start: str, end: str) -> dict:
"""
Return monthly Bedrock costs grouped by a cost allocation tag.
Requires tags activated in Billing console.
tag_key example: "project" or "team"
"""
ce = boto3.client("ce", region_name="us-east-1")
response = ce.get_cost_and_usage(
TimePeriod={"Start": start, "End": end},
Granularity="MONTHLY",
Filter={
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
GroupBy=[
{"Type": "TAG", "Key": tag_key}
],
Metrics=["UnblendedCost"]
)
return response["ResultsByTime"]
Valid Metrics values for Bedrock
UnblendedCost— what the account is actually charged; use this for most Bedrock reportingBlendedCost— amortized across consolidated billing; less meaningful for Bedrock since no RI/SP appliesUsageQuantity— token counts; pair with USAGE_TYPE grouping to get per-model token volumesNormalizedUsageAmount— not meaningful for Bedrock (relevant only for EC2 normalization)
Pagination
get_cost_and_usage returns a NextPageToken when results exceed one page. Handle it:
def paginated_cost_query(params: dict) -> list:
ce = boto3.client("ce", region_name="us-east-1")
results = []
while True:
response = ce.get_cost_and_usage(**params)
results.extend(response["ResultsByTime"])
token = response.get("NextPageToken")
if not token:
break
params["NextPageToken"] = token
return results
4. Saved Reports and Scheduled Exports
Cost Explorer saved reports
Cost Explorer allows saving report configurations (filters, groupings, date range, chart type) as named reports accessible in the console. There is no public API to programmatically create or enumerate saved Cost Explorer reports — they are console-only artifacts.
Scheduled dashboard email delivery (GA April 2026)
AWS Billing and Cost Management dashboards now support scheduled email delivery. Configuration:
- Daily, weekly, or monthly cadence
- Recipients receive a secure link to a password-protected PDF
- The PDF is point-in-time and does not contain raw data — it is a rendered screenshot of the dashboard
- For Bedrock reporting, configure a dashboard with SERVICE filter set to Amazon Bedrock before scheduling
This is distinct from CUR data exports, which are file-based and machine-readable.
Cost and Usage Report (CUR) scheduled exports to S3
For automated ingestion, CUR exports are the correct path:
- Configure via AWS Data Exports console or
aws cur put-report-definition - Exports land in S3 as Parquet or CSV, partitioned by billing period
- Bedrock line items appear with
product_product_name = "Amazon Bedrock"andline_item_usage_typecarrying the model+token type string - Export frequency: daily refresh with ~24-hour lag
Lambda-based automated reporting
A common pattern for Bedrock cost dashboards:
import boto3
import json
from datetime import date, timedelta
def lambda_handler(event, context):
ce = boto3.client("ce")
end = date.today().isoformat()
start = (date.today() - timedelta(days=30)).isoformat()
data = ce.get_cost_and_usage(
TimePeriod={"Start": start, "End": end},
Granularity="DAILY",
Filter={
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
GroupBy=[{"Type": "DIMENSION", "Key": "USAGE_TYPE"}],
Metrics=["UnblendedCost", "UsageQuantity"]
)
# Write to S3 for downstream consumption
s3 = boto3.client("s3")
s3.put_object(
Bucket="your-finops-bucket",
Key=f"bedrock-costs/{end}.json",
Body=json.dumps(data["ResultsByTime"])
)
return {"statusCode": 200, "report_date": end}
Schedule via EventBridge rule (rate(1 day)).
5. Forecasting Accuracy for Bedrock Workloads
Why Bedrock forecasting is structurally unreliable
Cost Explorer’s forecasting engine is calibrated for steady-state infrastructure spend — the canonical use case is EC2 reserved capacity with predictable utilization curves. Bedrock workloads have fundamentally different characteristics:
EC2 (forecasting works well):
- Hourly billing on persistent instances
- Usage is bounded by instance count × hours
- Seasonal patterns are learnable (weekday/weekend, business hours)
- Mean reversion is strong — a spike from a deployment typically returns to baseline
Bedrock (forecasting degrades quickly):
- Token-based billing: cost is a function of prompt length × model × call volume
- Prompt length is opaque to Cost Explorer — it sees aggregate token counts, not per-request structure
- Agent workloads compound unpredictably: multi-step reasoning chains can amplify token counts 5–20x vs a simple query
- Model mix changes (switching Claude 3.5 Haiku to Claude 3.5 Sonnet) cause step-function cost increases that break the model’s trend line
- Cross-region inference adds routing overhead that is not predictable from historical patterns
Practical consequence: Cost Explorer forecasts for Bedrock typically have errors of ±30–60% over a 30-day horizon when workloads are in active development. The forecast becomes more reliable (±10–20%) only after 90+ days of stable, unchanging workload composition.
Workaround: driver-based forecasting
Rather than relying on Cost Explorer’s statistical forecast, derive a forward estimate from application metrics:
- Establish a cost-per-inference metric from CloudWatch (invocation count × average tokens × model rate)
- Apply business-level growth assumptions (requests/day projection) to that unit cost
- Use Cost Explorer history to validate the unit cost, not to project the curve
6. Cost Explorer Anomaly Detection vs AWS Cost Anomaly Detection
These are not two separate products — AWS Cost Anomaly Detection is a feature of the Cost Management suite that sits alongside Cost Explorer. The distinction is architectural, not organizational.
Cost Explorer built-in view
The Cost Explorer console includes an anomaly flag on individual service spend lines when a data point is statistically outside the historical range. This is a read-only visualization layer — there is no alerting, no root-cause analysis, and no subscription model.
AWS Cost Anomaly Detection (standalone feature)
Dedicated ML-based anomaly detection with:
- Monitors: define the scope (service, linked account, cost category, or tag)
- Alert subscriptions: SNS topic or email, with configurable thresholds (absolute $ or percentage)
- Root-cause analysis: identifies which service, usage type, or account drove the anomaly
- Evaluation cadence: runs approximately 3× per day after billing data refreshes
For Bedrock, the recommended setup is a Service-level monitor scoped to Amazon Bedrock:
import boto3
ce = boto3.client("ce", region_name="us-east-1")
monitor = ce.create_anomaly_monitor(
AnomalyMonitor={
"MonitorName": "BedrockAnomalyMonitor",
"MonitorType": "DIMENSIONAL",
"MonitorDimension": "SERVICE"
}
)
subscription = ce.create_anomaly_subscription(
AnomalySubscription={
"MonitorArnList": [monitor["MonitorArn"]],
"SubscriptionName": "BedrockDailyAlert",
"Threshold": 20.0, # Alert if anomaly exceeds $20
"Frequency": "DAILY",
"Subscribers": [
{"Address": "finops-team@example.com", "Type": "EMAIL"}
]
}
)
Key operational difference
Cost Explorer anomaly visualization is retrospective and passive. AWS Cost Anomaly Detection with SNS is the alert path — it is what pages your team when a runaway agent runs 200k inference calls overnight. Common Bedrock-specific anomaly triggers: new developer accessing a premium model without rate limits, an agent retry loop hitting an unhandled exception and re-invoking thousands of times, or a prompt cache miss pattern after a model version upgrade.
7. Usage Type Groups for Bedrock in Cost Explorer
Usage type groups are Cost Explorer’s mechanism for aggregating the region-prefixed usage type strings into logical categories. They prevent the proliferation of USE1-InputTokens-Claude, USW2-InputTokens-Claude, EUW1-InputTokens-Claude etc. into separate rows when you want a cross-region total.
Native usage type groups for Bedrock
Cost Explorer does not ship with pre-built usage type groups for Bedrock the way it does for EC2 (where “EC2: Running Hours” aggregates across instance families). Bedrock usage type groups must be constructed by the operator.
The practical approach is to use USAGE_TYPE with MatchOptions: STARTS_WITH filtering:
# Aggregate all input tokens across all models and regions
input_token_filter = {
"And": [
{
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
{
"Dimensions": {
"Key": "USAGE_TYPE",
"Values": ["InputTokens"],
"MatchOptions": ["CONTAINS"]
}
}
]
}
# Aggregate all Claude-family spend across regions
claude_filter = {
"And": [
{
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
{
"Dimensions": {
"Key": "USAGE_TYPE",
"Values": ["Claude"],
"MatchOptions": ["CONTAINS"]
}
}
]
}
Cost Categories as a substitute for usage type groups
AWS Cost Categories allow creating rule-based logical groups that appear as a first-class dimension in Cost Explorer:
Rule: IF USAGE_TYPE CONTAINS "InputTokens" THEN category = "Bedrock-Input"
Rule: IF USAGE_TYPE CONTAINS "OutputTokens" THEN category = "Bedrock-Output"
Rule: IF USAGE_TYPE CONTAINS "CacheReadInputTokens" THEN category = "Bedrock-Cache-Read"
Rule: IF USAGE_TYPE CONTAINS "CacheWriteInputTokens" THEN category = "Bedrock-Cache-Write"
Cost Categories are configured in the Billing console and take up to 24 hours to backfill. Once active, use GroupBy: COST_CATEGORY in API calls.
8. Filtering Across Product Codes: Bedrock + Marketplace + SageMaker
Where Bedrock charges appear outside the Amazon Bedrock service line
Two cases cause Bedrock-adjacent spend to appear under different service lines:
Case 1: Bedrock model evaluation
Model evaluation jobs in Bedrock are billed under Amazon SageMaker line items, not under Amazon Bedrock. This is a known billing quirk. When reconciling total AI spend, run a parallel query for SageMaker filtered to evaluation usage types.
Case 2: Third-party models via AWS Marketplace
If your organization subscribes to models distributed through AWS Marketplace (some Llama variants, specialized fine-tuned models from ISVs), those charges appear under the AWS Marketplace service line, not Amazon Bedrock. The product code is aws-marketplace and the usage type strings vary by vendor.
Multi-product filter for total AI workload cost
def total_ai_workload_cost(start: str, end: str) -> dict:
"""
Captures native Bedrock + Marketplace model subscriptions +
SageMaker model evaluation that is billed separately.
"""
ce = boto3.client("ce", region_name="us-east-1")
response = ce.get_cost_and_usage(
TimePeriod={"Start": start, "End": end},
Granularity="MONTHLY",
Filter={
"Or": [
{
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
{
# Marketplace model subscriptions
"Dimensions": {
"Key": "SERVICE",
"Values": ["AWS Marketplace"],
"MatchOptions": ["EQUALS"]
}
},
{
# Bedrock model evaluation jobs
"And": [
{
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon SageMaker"],
"MatchOptions": ["EQUALS"]
}
},
{
"Dimensions": {
"Key": "USAGE_TYPE",
"Values": ["ModelEvaluation"],
"MatchOptions": ["CONTAINS"]
}
}
]
}
]
},
GroupBy=[{"Type": "DIMENSION", "Key": "SERVICE"}],
Metrics=["UnblendedCost"]
)
return response["ResultsByTime"]
SageMaker inference endpoints vs Bedrock
SageMaker real-time inference endpoints (dedicated endpoints for custom models) are a separate architectural choice from Bedrock on-demand inference. Their costs appear under Amazon SageMaker with usage types like ml.g5.xlarge-Hrs. These are not Bedrock charges and should be tracked in a separate cost category.
9. Granularity Options for Bedrock in Cost Explorer
Available granularities
| Granularity | Available for Bedrock | Notes |
|---|---|---|
MONTHLY |
Yes | Default; always available via API and GUI |
DAILY |
Yes | Available with no additional configuration |
HOURLY |
Partial | See below |
Hourly granularity — the Bedrock caveat
Cost Explorer supports hourly granularity, but Bedrock cost data is currently available at daily granularity at finest grain in Cost Explorer. The CUR 2.0 documentation confirms that native Bedrock attribution methods deliver aggregated billed dollars “with the finest grain being per usage type per day.”
Hourly granularity in Cost Explorer is primarily designed for EC2 resource-level data. Enabling it for non-EC2 services like Bedrock typically returns the daily total distributed across hours with uniform distribution — not actual per-hour measurement.
Cost of enabling hourly granularity: $0.00000033 per usage record, billed daily for the trailing 14 days of hourly records hosted in Cost Explorer.
Practical recommendation
For Bedrock operational dashboards, use DAILY granularity. For capacity planning and trend analysis, use MONTHLY. For sub-daily monitoring of Bedrock invocations and token volumes, use CloudWatch metrics (AWS/Bedrock namespace: Invocations, InputTokenCount, OutputTokenCount) which are available at 1-minute resolution.
10. RI/SP Coverage Reports: Bedrock Does Not Appear
Why Bedrock is absent from RI and Savings Plan coverage reports
RI (Reserved Instance) and Savings Plan coverage reports in Cost Explorer track the percentage of your on-demand usage that is covered by a commitment. These reports are scoped to services where commitments are available:
- RI coverage: EC2, RDS, ElastiCache, OpenSearch, Redshift, DynamoDB
- Compute Savings Plans coverage: EC2, Fargate, Lambda
- SageMaker Savings Plans coverage: SageMaker inference endpoints
Amazon Bedrock has no RI or Savings Plan instrument. On-demand Bedrock usage is not eligible for any commitment discount mechanism. If you run a coverage report and filter to Amazon Bedrock, it will either return empty results or show 0% coverage with 100% on-demand — which is technically correct but misleading.
What does show coverage for AI workloads
- SageMaker Savings Plans: Apply to SageMaker inference endpoints (your own model deployments), not to Bedrock on-demand calls
- Bedrock Provisioned Throughput: Bedrock’s own commitment mechanism — purchase a model unit (MU) for a defined throughput level at a fixed hourly rate. This is tracked in CUR as
ProvisionedThroughputusage type lines, distinct from on-demand token lines. It does not appear in Cost Explorer’s Savings Plan coverage reports; it appears as a usage cost under Amazon Bedrock.
Provisioned Throughput vs on-demand in Cost Explorer
# Separate provisioned throughput from on-demand token costs
provisioned_filter = {
"And": [
{
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
{
"Dimensions": {
"Key": "USAGE_TYPE",
"Values": ["ProvisionedThroughput"],
"MatchOptions": ["CONTAINS"]
}
}
]
}
11. Cost Explorer API Rate Limits and Caching Strategies
Rate limits
The Cost Explorer API enforces per-account rate limits. The primary operations and their documented limits:
| Operation | Rate limit | Notes |
|---|---|---|
GetCostAndUsage |
~5 req/sec sustained | Exact TPS not published; observed limit |
GetCostForecast |
Lower than GetCostAndUsage | Less critical path |
GetDimensionValues |
~5 req/sec | Use for filter validation |
Exceeding limits returns LimitExceededException. This is a hard stop — no burst allowance. AWS does not publish exact TPS for Cost Explorer APIs; the working assumption from production incidents is 5 req/sec per account, with backoff required on LimitExceededException.
Per-call pricing
Each paginated API call costs $0.01. A dashboard making 100 queries/day costs $1/day ($30/month). Design queries to be broad and filter in application code rather than issuing many narrow API calls.
Caching strategy for dashboards
Pattern 1: Lambda + S3 cache with TTL
import boto3
import json
from datetime import datetime, timedelta
CACHE_BUCKET = "your-finops-cache"
CACHE_TTL_HOURS = 6
def get_cached_bedrock_costs(start: str, end: str) -> dict:
s3 = boto3.client("s3")
cache_key = f"bedrock-cost-cache/{start}-{end}.json"
try:
obj = s3.get_object(Bucket=CACHE_BUCKET, Key=cache_key)
cached = json.loads(obj["Body"].read())
cached_at = datetime.fromisoformat(cached["cached_at"])
if datetime.utcnow() - cached_at < timedelta(hours=CACHE_TTL_HOURS):
return cached["data"]
except s3.exceptions.NoSuchKey:
pass
# Cache miss: fetch from Cost Explorer
ce = boto3.client("ce", region_name="us-east-1")
response = ce.get_cost_and_usage(
TimePeriod={"Start": start, "End": end},
Granularity="DAILY",
Filter={
"Dimensions": {
"Key": "SERVICE",
"Values": ["Amazon Bedrock"],
"MatchOptions": ["EQUALS"]
}
},
GroupBy=[{"Type": "DIMENSION", "Key": "USAGE_TYPE"}],
Metrics=["UnblendedCost", "UsageQuantity"]
)
to_cache = {
"cached_at": datetime.utcnow().isoformat(),
"data": response["ResultsByTime"]
}
s3.put_object(
Bucket=CACHE_BUCKET,
Key=cache_key,
Body=json.dumps(to_cache)
)
return response["ResultsByTime"]
Pattern 2: EventBridge-scheduled refresh
Run a daily Lambda that pre-populates a DynamoDB or S3 cache at a known time (e.g., 06:00 UTC, after Cost Explorer data refreshes). Dashboard queries hit the cache exclusively. Cost Explorer API is called once per day, not on demand.
Design rules for multi-team dashboards:
- Never call Cost Explorer directly from a web frontend — always proxy through a cache layer
- Batch multiple date range queries into a single wide query and slice in application code
- Use
MONTHLYgranularity for historical trend views (fewer rows = fewer pages = fewer API charges) - Scope historical lookback to 90 days for operational dashboards; retrieve full 13-month history only for quarterly reviews
12. Cost Explorer vs Athena/CUR: Decision Guide for Bedrock Analysis
Use Cost Explorer when
- You need a quick operational answer: “What did Bedrock cost last week by model?”
- You want GUI visualization without infrastructure setup
- You need anomaly alerts (Cost Anomaly Detection requires Cost Explorer to be enabled)
- You are building a dashboard that queries weekly or daily, not in real time
- Multi-account rollup in an AWS Organization is the requirement
Use Athena + CUR when
- You need per-request-level attribution (CUR 2.0 with IAM principal data provides line items per inference call)
- You need to join Bedrock billing data with application-level data (request IDs, user IDs, tenant IDs)
- You need sub-day granularity: CUR 2.0 refreshes hourly, giving ~1-hour resolution vs Cost Explorer’s 24-hour lag
- You need
USAGE_TYPEtext patterns beyond what Cost Explorer’s filter operators support (e.g., complex regex against model names) - You are running analyses that would require >500 Cost Explorer API calls — Athena at ~$5/TB scanned is cheaper for bulk historical queries
- You need to audit prompt cache efficiency:
CacheReadInputTokens / (CacheReadInputTokens + CacheWriteInputTokens)requires arithmetic across line items, which Cost Explorer cannot do
Hybrid pattern (recommended for production)
CUR 2.0 (Parquet, S3) → Athena (ad-hoc analysis, join with app data)
↓
Cost Explorer API (operational dashboards, anomaly detection, budget alerts)
↓
AWS Budgets (threshold alerts with forecast-based warnings)
Cost Explorer is the operational surface. CUR/Athena is the analytical surface. They complement each other — Cost Explorer cannot do joins or arithmetic; Athena cannot send anomaly alerts.
CUR 2.0 Bedrock columns of interest
| Column | Description |
|---|---|
line_item_product_code |
AmazonBedrock |
line_item_usage_type |
e.g., USE1-InputTokens-Claude |
line_item_operation |
InvokeModel, Converse |
line_item_usage_amount |
Token count for the period |
line_item_unblended_cost |
Dollar cost |
product_model_id |
Model identifier (CUR 2.0 only) |
resource_tags_user_* |
Custom cost allocation tags |
split_line_item_parent_resource_id |
Links to inference profile ARN when AIPs are used |
CUR 2.0 with IAM principal data enabled adds:
| identity_iam_principal_arn | ARN of the caller (user, role, or assumed role) |
This last column is unavailable in Cost Explorer and is the primary reason to reach for CUR/Athena when you need per-team or per-developer attribution at caller identity granularity.
Reference: Filter Dimension Keys
Valid dimension keys for get_cost_and_usage Filter and GroupBy:
AZ
INSTANCE_TYPE
LEGAL_ENTITY_NAME
INVOICING_ENTITY
LINKED_ACCOUNT
LINKED_ACCOUNT_NAME
OPERATION
PLATFORM
PURCHASE_TYPE
SERVICE
SERVICE_CODE
TENANCY
RECORD_TYPE
USAGE_TYPE
USAGE_TYPE_GROUP
REGION
SCOPE
DATABASE_ENGINE
DEPLOYMENT_OPTION
OPERATING_SYSTEM
SUBSCRIPTION_ID
BILLING_ENTITY
RESERVATION_ID
RESOURCE_ID
RIGHTSIZING_TYPE
SAVINGS_PLAN_ARN
SAVINGS_PLANS_TYPE
PAYMENT_OPTION
AGREEMENT_END_DATE_TIME_AFTER
AGREEMENT_END_DATE_TIME_BEFORE
INVOICING_ENTITY
For Bedrock, the operationally useful subset is: SERVICE, USAGE_TYPE, LINKED_ACCOUNT, OPERATION, REGION. TAG is used via GroupBy with {"Type": "TAG", "Key": "<tag-key>"} syntax, not as a Dimension key.
Sources
- Track, allocate, and manage your generative AI cost and usage with Amazon Bedrock
- Introducing granular cost attribution for Amazon Bedrock
- Track Amazon Bedrock Costs by Caller Identity with IAM Principal-Based Cost Allocation
- get_cost_and_usage — Boto3 documentation
- GetCostAndUsage — AWS Billing and Cost Management API Reference
- Best practices for the AWS Cost Explorer API
- Understanding your Amazon Bedrock Cost and Usage Report data
- Application inference profiles — Amazon Bedrock
- Track usage and costs in Amazon Bedrock
- Estimating cost for Cost Explorer hourly granularity
- Scheduling email delivery of dashboard reports
- AWS Billing and Cost Management Dashboards Now Supports Scheduled Email Delivery (April 2026)
- Amazon Bedrock now supports cost allocation by IAM user and role (April 2026)
- Manage AI costs with Amazon Bedrock Projects
- AWS Cost Anomaly Detection