---
title: "Pricing one Amazon Bedrock prompt from the token counts it returns"
description: "You send a prompt to a model on Amazon Bedrock and get a sensible answer back. Then you wonder what that one exchange cost."
source: "https://confidentprep.com/blog/pricing-one-amazon-bedrock-prompt-from-the-token-counts-in-its-response/"
date: "2026-10-14"
token_estimate: 2870
---

# Pricing one Amazon Bedrock prompt from the token counts in its response

You send a prompt to a model on Amazon Bedrock and get a sensible answer back. Then you wonder what that one exchange cost. The answer is already in the response: every Converse call returns a `usage` block that counts the tokens you sent and the tokens the model generated.

This article shows that one prompt's cost is two multiplications and a sum. Multiply the input count by the model's input rate and the output count by its output rate, using the rates for your Region and service tier, then add the two. The walkthrough does this from the AWS CLI. You make one call, read the counts and do the arithmetic. Then you cap the output on purpose to see which half of the cost you actually control.

## The Converse response already counts your tokens

A *token* is the unit that both the response's usage counts and Bedrock's rate tables are measured in. For text models, the rate tables list a separate price per one million input tokens and per one million output tokens. Pricing depends on the modality, the provider and the model.

The Converse API gives you one consistent request shape that works with all Bedrock models that support messages. You write the code once and use it with different models. It is available only on the `bedrock-runtime` endpoint.

In the response, the `usage` field reports the tokens passed to the model in the request and the tokens generated in the response. The documentation's own example returns 125 `inputTokens`, 60 `outputTokens` and 185 `totalTokens`. It also returns a `metrics` field with the call's latency in milliseconds.

Think of the `usage` block as a till receipt stapled to every purchase. You still need the price list to turn quantities into money, but you no longer have to guess the quantities.

![The CLI sends a Converse request to bedrock-runtime and gets back output, stopReason, usage and metrics](visuals/visual-01.svg)

*One Converse call returns the answer and the token counts you need to price it*

## Set up a caller that is allowed to invoke

To call `Converse`, you need permission for the `bedrock:InvokeModel` operation. To stream with `ConverseStream`, you need `bedrock:InvokeModelWithResponseStream` instead.

Before you start, check that the identity your CLI uses has that permission. Pick a text model you have access to and note its model ID. `modelId` is the required parameter in a Converse request, and it names the resource that runs the inference. Keep both values in shell variables so the commands below can be pasted unchanged:

```bash
export MODEL_ID="<your-model-id>"
export AWS_REGION="<your-region>"
```

Note the Region carefully, because it changes the price. One model is listed at $0.50 per million input tokens and $1.50 per million output tokens in US East (N. Virginia), US East (Ohio) and US West (Oregon). In Asia Pacific (Mumbai), the same model is listed at $0.59 and $1.76 (retrieved 2026-10-14).

## One call, one usage block

Send a short prompt and set a ceiling on the output. `maxTokens`, set inside `inferenceConfig`, is the maximum number of tokens to allow in the generated response. The prompt below is the one the documentation uses in its own example:

```bash
aws bedrock-runtime converse \
  --model-id "$MODEL_ID" \
  --messages '[{"role":"user","content":[{"text":"Create a list of 3 pop songs."}]}]' \
  --inference-config '{"maxTokens":300}' \
  --query '{usage: usage, stop: stopReason}'
```

Look for output shaped like the documented example. It should include an `inputTokens` count, an `outputTokens` count, a `totalTokens` count and a stop reason, which the documentation shows as `end_turn` for a finished answer. Your exact numbers will differ by model.

Your `inputTokens` figure may be larger than your short sentence seems to justify. With Mistral AI and Meta models, the Converse API embeds your input in a model-specific prompt template that enables conversations. In practice, this is one reason that counting the words in your prompt is a poor estimate. The `usage` block is the figure to trust.

![Input and output tokens each have their own rate; total tokens is only their sum](visuals/visual-02.svg)

*Each usage field answers a different question about what you are billed for*

## The cost is two multiplications and a sum

The rate tables quote prices per one million tokens and list input and output separately. The formula follows from that:

> cost = inputTokens × input rate ÷ 1,000,000 + outputTokens × output rate ÷ 1,000,000

Do not multiply `totalTokens` by a single rate. In many rows of the rate tables, output costs more than input. For the model above, it costs three times as much: $1.50 against $0.50 per million (retrieved 2026-10-14). If you price the total at the input rate, you understate the cost. If you price it at the output rate, you overstate it.

![Input tokens times the input rate and output tokens times the output rate are summed into the prompt's cost](visuals/visual-03.svg)

*Input and output tokens are priced separately, then the two results are added*

Here is the documented example worked through. Take 125 input tokens and 60 output tokens and price them at $0.50 and $1.50 per million (retrieved 2026-10-14).

- Input costs 125 × 0.50 ÷ 1,000,000 = $0.0000625.
- Output costs 60 × 1.50 ÷ 1,000,000 = $0.00009.
- The prompt cost $0.0001525 in total.

Output was fewer than half as many tokens as input, yet it made up more than half of the cost.

You can also have the shell do the arithmetic. Fill in the two rates from the pricing page for your model, Region and tier:

```bash
IN_RATE=0.50; OUT_RATE=1.50
aws bedrock-runtime converse \
  --model-id "$MODEL_ID" \
  --messages '[{"role":"user","content":[{"text":"Create a list of 3 pop songs."}]}]' \
  --query '[usage.inputTokens, usage.outputTokens]' --output text |
awk -v i="$IN_RATE" -v o="$OUT_RATE" \
  '{printf "in=%d out=%d cost=$%.7f\n", $1, $2, ($1*i + $2*o)/1000000}'
```

Be careful with the worked examples further down the pricing page. Several of them quote rates per 1,000 tokens rather than per million. One example prices a summarisation request at $0.008 and $0.024 per 1,000 tokens. The examples are useful for seeing the method. A sensible habit is still to take your rates from the rate table row for your own model, and to check which unit that row uses.

![Input costs $0.0000625 and output $0.00009, so the prompt totals $0.0001525](visuals/visual-04.svg)

*The documented 125-in, 60-out response priced at one model's US East rates*

## Break it on purpose: starve the output

Run the first command again, this time with `"maxTokens":10`. The ceiling is a maximum, not a target. If the answer needs more than ten tokens, generation stops at the ceiling and the stop reason reads `max_tokens`. That is the same value the documentation shows when a streamed response hits its limit. If the model finishes within ten tokens, you will see `end_turn` and a smaller output count instead.

A list of three songs with artist names will usually need more than ten tokens, so expect the cut-off case. Either way, `outputTokens` will not exceed ten.

Now compare the two `usage` blocks. You sent the same prompt to the same model, so `inputTokens` should be unchanged. This is the point worth keeping: `maxTokens` limits only the output half of the cost. The input half is fixed the moment you send the request, whether or not the answer turns out to be useful.

![Two runs of one prompt keep the same input count; the 10-token cap limits output and may end with max_tokens](visuals/visual-05.svg)

*Lowering maxTokens can shrink output, but the input count stays the same*

In practice, a truncated answer that you have to resend costs more than one complete answer would have, because you pay for the input twice. A sensible rule is to cap output to protect against runaway responses, not to save money on answers you actually need.

## Streaming, caching and tiers change where you read the numbers

**Streaming.** With `ConverseStream`, the token counts do not arrive with the text. They come in a `metadata` event, sent once per response after `messageStop`, which carries `usage` and `metrics`. A cost script for streaming has to wait for that final event before it can calculate anything.

**Caching.** If you use prompt caching, the `usage` field also reports `cacheReadInputTokens` and `cacheWriteInputTokens`. These are the tokens read from the cache and written to the cache. Some models list separate prices for cache reads and cache writes. One model, for example, shows $0.30 per million for cache reads against $3.00 per million for ordinary input (retrieved 2026-10-14). When those fields appear, give each one its own term in the formula.

**Service tiers.** The `serviceTier` request field accepts `reserved`, `priority`, `default` or `flex`, and the response tells you which tier the request used. For many providers, Priority is priced at a 75% premium to Standard, and Flex at a 50% discount (retrieved 2026-10-14).

Applied to the documented example, the $0.0001525 Standard cost becomes about $0.00026688 on Priority and $0.00007625 on Flex. The token counts are identical, but the three costs are not.

![The same call costs $0.0001525 on Standard, about $0.00026688 on Priority and $0.00007625 on Flex](visuals/visual-06.svg)

*Identical token counts cost different amounts depending on the service tier used*

Batch inference is a separate route. Select models are offered for batch inference at a 50% lower price than on-demand inference. This walkthrough covers only interactive Converse calls.

## What this exercise cost, and what to clean up

Each call in this walkthrough uses a few hundred tokens at most. At rates like those above, the whole exercise comes to a small fraction of a cent. That is an estimate from the arithmetic shown, not a quote.

Cleanup is light. Bedrock does not store the text, images or documents you provide as content; that data is only used to generate the response. The walkthrough only makes calls, so in practice the cleanup is to unset the two shell variables.

One thing may persist. If you attached `requestMetadata` tags, they are recorded with the request in your model invocation logs. Those logs are set up separately, so whether to keep them is your decision.

## Key takeaways

- Every `Converse` response carries `usage.inputTokens` and `usage.outputTokens`. Those two counts are what you price, not the number of words in your prompt.
- Cost is input tokens × input rate plus output tokens × output rate, each divided by one million. Never price `totalTokens` at a single rate.
- Take the rate for your exact model, Region and tier from the rate table, and check its unit, because some worked examples on the same page quote rates per 1,000 tokens.
- `maxTokens` sets a ceiling on output, not a target. It limits only the output half of the cost; you pay for the input in full even when the answer is cut off.
- Streaming moves the counts into the final `metadata` event. Caching adds cache read and cache write counts that some models price separately.

This settles the cost of a single on-demand text prompt. It does not settle the cost of image, video or speech inputs, which some models price differently. It also does not cover features that run alongside the model call, such as guardrails, knowledge bases or prompt routing, each of which is metered on its own terms.
