On Bedrock's classic bedrock-runtime surface you have two ways to talk to Claude: InvokeModel, which passes Anthropic's native JSON body through untouched, and Converse, a higher-level API that AWS recommends because it gives you a unified parameter set that works across the foundation models Bedrock hosts. If your platform team wants one integration that can serve Claude today and potentially other models tomorrow, Converse is the abstraction designed for exactly that.
Messages and roles: the conversation is yours to carry
Like Anthropic's own Messages API, Converse is stateless: the service does not remember previous turns. Every request carries the entire conversation history as a list of messages that alternate between the user role and the assistant role. Each message contains one or more typed content blocks — text, images, documents, and (as we'll see below) tool-related blocks. To continue a conversation, you append the model's last reply to your history as an assistant message, add the new user message, and send the whole list again.
Two practical consequences follow. First, your application needs somewhere to store history between turns — a session store, a database row, whatever fits your stack. Second, history grows with every turn and every token of it is billed as input, so long-running conversations eventually need trimming or summarizing. Prompt caching (supported for Claude on Bedrock) softens the cost of resending a long, stable prefix.
System prompts live outside the message list
Instructions that define the assistant's role, tone, and boundaries do not go into the messages array. Converse carries them in a dedicated system field, separate from the user/assistant exchange — the same separation Anthropic's native API makes. Keep durable instructions ("you are a claims-triage assistant; never provide legal advice") in the system prompt and reserve messages for the actual dialogue. This separation also makes the system prompt a natural target for prompt caching, since it is identical across requests.
The tool-result cycle
Tool use in Converse follows a request–response loop between your code and the model:
1. You declare tools. The request includes a tool configuration listing each tool's name, a description of what it does, and a schema for its input. Claude never executes anything itself on Bedrock — server-side tools such as web search and code execution are not available there — so every tool is a function your application implements.
2. The model asks to use one. Instead of a final answer, the response contains a toolUse content block: the tool's name, the input the model chose, and an identifier for this specific call, with a stop reason signalling that the model is waiting on a tool.
3. You run the tool and reply with a toolResult. Execute the function, then send a new user message containing a toolResult block that carries the matching identifier and your output. The model reads it and either answers or requests another tool. The full loop, with runnable detail, is covered in Implementing Tool Use via the Bedrock Converse API.
Documents, PDFs, and one Claude-specific wrinkle
Converse accepts document inputs for Claude, including PDFs — but with a nuance worth knowing before you build a document pipeline: on Converse, full visual PDF analysis (layout, charts, scanned pages) requires citations to be enabled; without citations you get basic text extraction only. If you need full control over PDF handling, Anthropic's guidance is to use InvokeModel instead. Also remember the runtime surface's 20 MB request payload cap when embedding files.
Permissions and audit
The caller needs the bedrock:Converse IAM action (plus bedrock:ConverseStream for streaming). Note that denying bedrock:InvokeModel automatically blocks Converse too — useful for admins writing deny policies. Converse calls are logged as CloudTrail management events by default, and Bedrock's model invocation logging can capture full request and response bodies for Converse if you enable it.
Where to go next
Decide between the two request styles with InvokeModel vs Converse, add incremental output with the ConverseStream guide, or see how images travel in Bedrock payloads.