requestMetadata key/value pairs your application attaches at invocation time, plus Managed AI Tags such as the model, Region, operation, and calling IAM principal. These become tags you can filter and group on in Cost Reports, Virtual Tags, Budgets, and Cost Alerts.
This unlocks request-level cost attribution that the CUR alone cannot provide. See the example use cases for scenarios such as per-customer margins, per-feature spend, and team chargeback.
AWS Bedrock LLM Enrichment is the native path for Bedrock: you enable Model Invocation Logging in AWS and Vantage reads the logs AWS already writes, with no telemetry to emit from your own applications. If your Bedrock traffic runs through an AI gateway, or you want to attribute spend across several providers from one stream, see Custom LLM Enrichment instead.
requestMetadata you attach at invocation time. Vantage does not collect or store your Bedrock prompt or completion content, and it is never written to a Vantage-owned artifact. This data is not used to train any models.How It Works
When logging is enabled, Amazon Bedrock records every model invocation (i.e.,InvokeModel, InvokeModelWithResponseStream, Converse, and ConverseStream) as a JSON record in your Model Invocation Logs. Each record includes token counts, the model, the calling identity, and the requestMetadata your application supplied. Vantage joins those records to your Bedrock CUR costs during AWS cost ingestion.
The enrichment pipeline runs through the following steps:
How Bedrock Costs Are Matched
Vantage does not match logs to costs on the model alone, because Bedrock prices the same model differently depending on how it was called. A logged invocation and a cost row are joined on the billing day, the token kind, and the following dimensions:input, output, cache_read, and cache_write.
inputTokenCount, so its input count already excludes cached tokens. Vantage accounts for this when normalizing, and does not subtract cache tokens a second time.Model Normalization
Model Invocation Logs and the CUR often identify the same model in different ways. A log record may carry an inference-profile ARN:anthropic.claude-opus-4-5, so the two sides join. On the cost side, Vantage reads the model identity from the resource ID when it contains a Bedrock foundation-model or inference-profile ARN, then falls back to the transformed model identifier and finally to the service name.
Models and token dimensions that Vantage cannot recognize are not guessed. An unmatchable record is recorded with its normalization reason and excluded from allocation rather than attributed to the wrong model.
How Cost Rows Are Split
For each matched Bedrock cost row, the cost is allocated proportionally across the metadata groups present in the Model Invocation Logs, weighted by token usage: Splits are additive: the sum of the enriched rows always equals the original Bedrock cost row. Existing Bedrock-level reports continue to show the same totals; enrichment only makes new dimensions available on the underlying rows.anthropic.claude-3-5-sonnet in us-east-1 is $120 for the day, covering 60M input tokens. The Model Invocation Logs for that day show:$120 row becomes three rows:$120. The leftover row carries the portion of the cost row’s tokens your logs do not cover. It keeps the original CUR dimensions and the vntg:ai: tags derived from the cost row, but none of your requestMetadata keys, so totals always reconcile and no dollars are lost.Data Freshness and Backfill
Enrichment runs inside the existing AWS cost ingestion pipeline, so it follows the same cadence as the rest of your AWS cost data. Month-to-date Bedrock rows are refreshed on every AWS data refresh, and recent days are reprocessed within a rolling three-day window so late-arriving logs are picked up. See the provider data refresh documentation for AWS timing. There is no Vantage-imposed backfill window: a billing period is enriched whenever it is processed while an active source exists, for as long as the matching logs remain in your bucket. Connecting a source does not, by itself, reprocess months that have already finished importing. Those periods are enriched the next time they are reprocessed, such as when AWS restates that month’s CUR or when the period is re-ingested through the AWS CUR backfill process.Prerequisites
Before you begin, make sure:- An active AWS billing (CUR) integration exists for the bucket’s AWS account, or for its management/payer account.
- You have a Vantage Organization Owner or Integration Owner role. See Role-Based Access Control.
Set Up AWS Bedrock LLM Enrichment
Setup has three steps: enable Model Invocation Logging in AWS, attachrequestMetadata to your invocations (optional, but recommended), and connect the log buckets in Vantage.
Step 1: Enable Bedrock Model Invocation Logging
In the AWS Bedrock console (or via the AWS API), enable Model Invocation Logging and choose an S3 bucket as the destination. Vantage ingests logs from S3 only; a CloudWatch-only destination is not supported. For full setup instructions, see the AWS documentation on model invocation logging.- One bucket per AWS account, for example a separate log bucket for Development, Staging, and Production.
- Multiple regional buckets on the same AWS account, for example one bucket for
eu-central-1and another forus-east-1.
Step 2: Configure Request Metadata (Recommended)
Request metadata lets you attribute Bedrock cost to per-request dimensions such as team, application, customer, and feature. You attach a flat map of string key/value pairs to each invocation, AWS records it in therequestMetadata field of the matching log record, and Vantage surfaces those pairs as tags. Costs for invocations without metadata are still split by the model, Region, operation, and IAM principal, but they will not carry your custom dimensions.
The way you attach metadata depends on the API:
ConverseandConverseStreamaccept arequestMetadatafield in the request body.InvokeModelandInvokeModelWithResponseStreamaccept theX-Amzn-Bedrock-Request-MetadataHTTP header.
- Set
requestMetadatain a shared client or LLM gateway so every invocation is tagged consistently, without relying on each caller to remember. - Choose stable, low-cardinality keys such as
team,environment, orfeaturefor easy aggregation, and reserve high-cardinality values such ascustomer_idorflow_run_idfor when you need per-entity tracing. - Avoid placing personally identifiable information (PII), credentials, or other sensitive data in request metadata. Values are stored in your logs and any system that reads them.
- Request metadata is only recorded when Model Invocation Logging is enabled in the Region where the call is made. Otherwise the invocation still succeeds, but no metadata is retained.
requestMetadata keys collides with one of those names, the value Vantage derives wins. The AWS account and IAM principal are always taken from the log record and cannot be set through requestMetadata.Step 3: Connect the Log Buckets in Vantage
In Vantage, navigate to the Integrations page and, under LLM Enrichment, select AWS Bedrock, then select the S3 buckets that receive your Bedrock logs. The connect screen walks you through granting read access and validating it.Select the buckets
Grant Vantage read access
- AWS Console
- AWS CLI
- Terraform
VantageCrossAccountRole: the name of your existing Vantage cross-account IAM role.ModelInvocationLoggingBuckets: a comma-separated list of destination bucket ARNs, each asarn:aws:s3:::your-bucket/*.
us-east-1, which only controls where the stack is created; it does not limit which bucket Regions are covered.s3:ListBucket and s3:GetBucketLocation. The grant above adds only object read on the log bucket (s3:GetObject, and the generated policy always includes s3:GetObjectAcl) plus the Bedrock logging-configuration read.kms:Decrypt separately. See KMS-Encrypted Buckets.Check permissions and connect
Manage AWS Bedrock Enrichment Sources
Manage your connected buckets from the AWS Bedrock integration page. The sources table lists each bucket with its AWS account, creation date, and Status (for example, Pending before an import starts, Importing while one runs, Stable once all imports succeed, Warning if only some imports fail, Error if all imports fail, or Paused if the source is stopped). Error details appear beneath the status. Paused sources show a Resume button, and each row has a ⋮ (More actions) menu with View import history and, for sources that are not paused, Stop.View Import History
In the sources table, open the row’s ⋮ (More actions) menu and select View import history to open the source’s Import History. The screen lists one row per billing period that ran enrichment, with columns for the Integration (with its account beneath), Status, Tokens Kept, Log Lines Kept, Bill Match, Billing Period, and Last Enriched At. When a run needs attention, the reason appears in the Status column. Lifecycle changes also appear as marker rows: Added when enrichment is first enabled for the bucket, and Paused or Resumed when you stop or resume it.Stop a Source
To stop a source, open the row’s ⋮ (More actions) menu and select Stop, then confirm in the Stop enrichment source dialog. This is a soft deactivation, not a hard delete: Vantage stops enriching new cost data for that bucket, but your existing enriched history is left unchanged, and the source stays visible in the list so you can bring it back at any time.Resume a Source
To resume a stopped source, select Resume in its row. Going-forward enrichment restarts on the next AWS data refresh. A paused bucket cannot be re-added through the connect flow; use Resume instead.View Enriched Costs on Cost Reports
Once enrichment runs, a single Bedrock CUR line is split into multiple rows, each carrying enrichment tags. You can filter and group by these tags anywhere tags are supported: Cost Reports, Virtual Tags, Budgets, and Cost Alerts. Because enrichment splits (allocates) your Bedrock costs, enrichment tags behave like Vantage’s cost allocation tags: you can build a Virtual Tag on them, but a cost can be allocated only once, so an enrichment tag can belong to only one allocation chain. Allocated values show the allocated badge (calculator icon) in the console.Enrichment Tag Reference
requestMetadata keys appear exactly as you send them, with no prefix. The dimensions Vantage derives and adds itself, such as the model identifier, carry a vntg:ai: prefix (for example, vntg:ai:model); this keeps them distinct from your keys and consistent with the AI tags Vantage applies across every provider you have connected. Because your key is just team (not provider-namespaced), the same key lines up across Bedrock, OpenAI, Anthropic, and the other providers, so you can group your entire AI stack by one team tag. Consistent key naming matters: team and Team are two different keys.
Vantage writes a tag only when the source data provides a reliable value for it, so the exact set you see depends on what your logs and CUR report. See Managed AI Tags for the full cross-provider schema.
Enrichment tags behave like any other provider tag in the console:
- To group: open the Group By menu, select Tag, and choose the tag key, for example
vntg:ai:model(values likeclaude-opus-4-5) or arequestMetadatakey such asteam. - To filter: open the Filters menu, click New Rule, select Tag, choose the Tag Key, then pick an operator and one or more values.
vntg:ai:* tags (such as vntg:ai:model); split rows also carry the requestMetadata from their usage slice. When a vntg:ai: key is present on both the cost row and the enrichment, the value derived from your CUR wins. The leftover row (usage not covered by your logs) keeps the original CUR dimensions and the applicable vntg:ai:* tags but carries none of your requestMetadata. The AWS account and IAM principal are always taken from the log record and can never be supplied through requestMetadata.team and purpose metadata attached at invocation time, alongside vntg:ai:model, so the same model can be compared across teams and workloads.

IAM Principal Normalization
Vantage derivesvntg:ai:principal_id from the caller identity (identity.arn) in each log record and normalizes it to a readable value:
- If your logs carry no principal, the match is not scoped by principal.
- If the cost row names a specific user or session, only invocations from that principal can match it.
- If the cost row names a bare IAM role, every logged session of that role can match it.
- If the cost row names a principal that matches none of the logged invocations, that row is left unenriched rather than attributed to the wrong caller.
- If some cost rows for the same model and day name a principal and others do not, the unattributed rows draw only from invocations that carry no principal, so usage is never counted against two callers.
vntg:ai:principal_id tag to your Group By.CUR 2.0 and IAM Principal Attribution
AWS Bedrock LLM Enrichment works with both AWS Legacy CUR and CUR 2.0. Vantage converts CUR 2.0 rows to a common format before enrichment runs, so the same join and cost-splitting behavior applies regardless of which CUR format your AWS integration uses. See CUR Format for how to enable CUR 2.0. CUR 2.0 can also attribute Bedrock cost by the calling IAM principal without Model Invocation Logs. When you enable Include caller identity (IAM principal) allocation data on the CUR 2.0 export, Vantage surfaces the caller as theaws:IamPrincipal tag (plus any activated aws:iamPrincipal:* tags), and copies its normalized value into vntg:ai:principal_id. You can use this alongside LLM Enrichment, but it is less detailed: it tells you which IAM role or user made the call, not the per-request dimensions (such as team, customer, or feature) that Model Invocation Logs capture. When both sources report a principal, the CUR value takes precedence.
The two paths support different attribution dimensions:
requestMetadata rather than on IAM principals.Troubleshooting
Most errors are displayed when you click Check Permissions or Connect. The tables below list the messages you may see, their cause, and how to resolve them. Expand a section for the relevant category.Permission and access errors
Permission and access errors
Bucket configuration and logging destination errors
Bucket configuration and logging destination errors
Connection setup errors
Connection setup errors
My Bedrock costs are not split per team or customer
My Bedrock costs are not split per team or customer
- Confirm your application is attaching
requestMetadatato Bedrock invocations. Costs from invocations without metadata are split by model, Region, operation, and IAM principal only. - Confirm Model Invocation Logging is enabled in the Region where the calls are made, and that a bucket for that Region is connected. Metadata is recorded only when logging is on for that Region.
- Allow a full AWS data refresh to complete after connecting. Enrichment applies on the next refresh.
Why aren't my Bedrock costs being split at all?
Why aren't my Bedrock costs being split at all?
- There is no active Model Invocation Log source for the account, the source is paused, or the log import has not completed successfully.
- The cost row is not a Bedrock usage row, or its model, Region, operation, inference scope, tier, or token type could not be matched to a logged invocation.
- The cost row is a batch inference row. Model Invocation Logging does not record asynchronous batch jobs, so batch costs pass through unchanged.
- The cost row reports an IAM principal that does not match any logged invocation.
- Your AWS integration still imports on the legacy cost pipeline, which has no enrichment stage.
My Bedrock totals changed after enabling enrichment
My Bedrock totals changed after enabling enrichment
My Bedrock spend is attributed to the wrong teams or customers
My Bedrock spend is attributed to the wrong teams or customers
KMS-Encrypted Buckets
If your log bucket is encrypted with AWS Key Management Service (KMS), Check Permissions reports a decryption error until Vantage can read the objects. Either remove encryption on the bucket, or grant the cross-account rolekms:Decrypt for the encrypting key and allow that role in the KMS key policy. The CloudFormation, CLI, and Terraform options in Step 3 grant S3 and Bedrock read access only, so KMS access must be added separately.
Use Cases
Each row below shows examplerequestMetadata keys to attach to your Bedrock calls and what that attribution enables in Vantage. The key names are examples; you choose your own, and Vantage surfaces whatever requestMetadata you send. “Attach” means including those key/value pairs in each invocation’s requestMetadata, as shown in Step 2. All rows assume Model Invocation Logging is enabled and the bucket is connected.
Frequently Asked Questions
What Vantage permissions do I need to enable this?
What Vantage permissions do I need to enable this?
What access does Vantage gain in my AWS account?
What access does Vantage gain in my AWS account?
s3:GetObject, s3:ListBucket, s3:GetBucketLocation, and kms:Decrypt for KMS-encrypted objects (generated policies may also include s3:GetObjectAcl), plus bedrock:GetModelInvocationLoggingConfiguration to auto-discover the log prefix and Region. The policy attaches to your existing cross-account role; no new role is created. See Step 3: Connect the Log Buckets in Vantage.Should I use this or Custom LLM Enrichment for Bedrock?
Should I use this or Custom LLM Enrichment for Bedrock?
Will this change my Bedrock totals or break existing reports?
Will this change my Bedrock totals or break existing reports?
How far back does Vantage enrich my Bedrock spend?
How far back does Vantage enrich my Bedrock spend?
Does this cover batch inference?
Does this cover batch inference?
What if I invoke Bedrock in multiple Regions or AWS accounts?
What if I invoke Bedrock in multiple Regions or AWS accounts?
Can I configure this via the Vantage API or Terraform?
Can I configure this via the Vantage API or Terraform?
Do my applications need code changes to invoke Bedrock?
Do my applications need code changes to invoke Bedrock?
requestMetadata, a standard Bedrock invocation parameter, to your calls.Does Vantage see my prompt content?
Does Vantage see my prompt content?
requestMetadata you attach at invocation time. Prompt and completion text are never collected or stored.