Messages API (Anthropic Compatible)¶
Generate conversational AI responses with Amazon Bedrock foundation models—including Claude, Nova, Llama, and more—through an Anthropic-compatible Messages API interface. Served under /anthropic by default; the examples below use $BASE, which includes that prefix.
At a glance¶
- One catalogue, not one vendor — name any chat model your regions serve: Anthropic Claude, Amazon Nova, Meta Llama, and every Bedrock Mantle model when Mantle is enabled.
- Multi-modal input — text, images, video and PDF documents in one conversation, from HTTP URLs, data URIs,
s3://URLs and Files APIfile-id:references. - Streaming, tool use, extended thinking, prompt caching — model permitting; see Feature compatibility.
- Bedrock Guardrails and service tiers — content filtering and
priority/flexlatency selection per request, through request headers. - Differs from the Anthropic API:
max_tokensis optional and a0budget still returns one token,inference_geoandcontainer(Agent Skills included) are accepted and ignored, andmcp_serversnever opens a connection — see Limits and behaviour to know. - Differs from the official SDK:
anthropic≥ 1.0 removedtemperature,top_pandtop_kfrommessages.create(); the gateway still accepts them on the wire, so send them throughextra_body.
Base URL and route prefix
By default, all Anthropic-compatible routes are prefixed with /anthropic. This means the Messages API is available at /anthropic/v1/messages instead of /v1/messages. You can customize this prefix using the ANTHROPIC_ROUTES_PREFIX configuration variable documented in HTTP Server and MCP.
The curl examples on this page use a $BASE variable that must include this prefix — set it to your scheme and host followed by ANTHROPIC_ROUTES_PREFIX:
export BASE="https://your-host/anthropic" # <scheme>://<host> + ANTHROPIC_ROUTES_PREFIX
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-5",
"max_tokens": 256,
"messages": [{"role": "user", "content": "Hello"}]
}'
Endpoints¶
| Endpoint | Method | What It Does | Powered By | MCP Tool |
|---|---|---|---|---|
/v1/messages | POST | Conversational AI with multi-modal support | Bedrock Converse API · Amazon Bedrock Mantle | anthropic_message |
/v1/messages/count_tokens | POST | Count tokens in a message without sending | Bedrock CountTokens API · Bedrock Mantle | anthropic_message_count_tokens |
Feature compatibility¶
| Feature | Status | Notes |
|---|---|---|
| Messages & Roles | ||
| Text messages | Full support for all text content | |
Image input (image) | HTTP URLs, data URIs, base64 | |
Document input (document) | PDF (base64/URL), plain text, content blocks | |
| Document citations | Citation locations in responses, streaming and non-streaming alike (PDF only on some models) | |
Search result input (search_result) | Pass search results as context | |
| System messages | System prompts | |
| Image & Document input from S3 | S3 URLs | |
Files API (file_id) | Reference uploaded files in document/image sources — see Files API | |
| Tool Calling | ||
Tool use (tools) | Full Anthropic-compatible schema | |
Tool choice (auto, any, tool) | Control tool selection behavior; Claude Opus and Sonnet 5.5 and later refuse any and tool with 400 | |
Tool choice none | Withdraws every declared tool; a conversation already containing a tool_use block keeps the tools that block names callable, and the model may call one again | |
Changing tools between turns | The tools declared on a turn are the only ones the model may call, whatever the replayed history names | |
| Parallel tool calls | Multiple tools in one turn | |
| Empty tool result | A tool that returns nothing is answered with a tool_result whose content is omitted, an empty string, or an empty list; the model is told the call ran and returned nothing | |
Web search tool (web_search) | Available on models with system tool support (e.g., Amazon Nova 2) | |
| Claude server tools | Bash, text editor, computer use (Claude 3.5+), memory (Claude 3.7+) | |
Browser & computer toolsets (browser_toolset_*, computer_toolset_*) | Accepted on the wire, with their browser_state results and toolset_name pairing. Served only where the model's own API runs them; elsewhere the request is refused by name — see Toolsets | |
MCP connector (mcp_servers, mcp_toolset) | Accepted and ignored: the model does not connect to remote MCP servers, so their tools never run. Declare the tools in tools and run them yourself — see MCP Connector | |
MCP block replay (mcp_tool_use, mcp_tool_result) | Accepted in conversation history and treated as an ordinary tool use and result; a repeated call comes back as tool_use, for you to run | |
Server tool result replay (web_search_tool_result, code_execution_tool_result, …) | Accepted in conversation history: send the assistant turn back unchanged and the recorded result is replayed to the model with the call it answered | |
| Generation Control | ||
max_tokens | Output length limits. Optional on this gateway (divergence from the Anthropic API, which requires it): the model's default output limit applies when omitted, except on a Bedrock Mantle-served model, whose API requires the field and is sent 4096. 0 — the prompt-cache pre-warm budget — is accepted and answered with one token rather than with nothing. Amazon Nova 2 drops the limit entirely under high reasoning effort and answers in full | |
temperature | Mapped to Bedrock inference params | |
top_p | Nucleus sampling control | |
top_k | Top-k sampling control | |
stop_sequences | Custom stop strings | |
| Thinking | ||
| Prompt caching | Cache prompts to reduce costs and latency | |
Context editing (context_management) | Claude models: clears older tool results and thinking blocks, reports applied_edits, and is honored by count_tokens. Accepted and ignored on other models. Compaction is not available — see Context Editing | |
| Extra model-specific params | Extra model-specific parameters not supported by the Anthropic API | |
| Streaming & Output | ||
| Text | Text messages | |
Streaming (stream: true) | Server-Sent Events (SSE). Bedrock only reports usage in the trailing event, so message_start.message.usage is always 0/0; read final counts from message_delta.usage instead | |
| Thinking content | Extended thinking output in content blocks | |
| Usage tracking | ||
| Input text tokens | Billing unit | |
| Output tokens | Billing unit | |
| Cache creation tokens | Prompt caching metrics (streaming and non-streaming) | |
| Cache read tokens | Prompt caching metrics | |
Cache creation by TTL (cache_creation) | Splits the cache creation tokens into ephemeral_5m_input_tokens and ephemeral_1h_input_tokens, when a per-TTL split is reported | |
Reasoning tokens (output_tokens_details) | Reported only by models that return a reasoning-token count; output_tokens remains the billed total | |
Service tier (usage.service_tier) | standard, priority or batch. Omitted when the request ran on a tier the Anthropic API has no name for (flex, reserved) | |
Server tool counters (usage.server_tool_use) | Always omitted, so web_search_requests is never reported — see Web Grounding | |
| Other | ||
Refusal details (stop_details) | Policy category and explanation behind stop_reason: "refusal", when the model reports them | |
| Metadata | Converse path: logged only. Mantle path: metadata.user_id is forwarded upstream | |
inference_geo | Accepted and ignored: data residency is set by the deployment's configured Bedrock regions, not per request — see Limits | |
container | Accepted and ignored in both forms, the identifier and the object: no container is created or reused, and no Agent Skill is loaded — see Limits | |
| Bedrock Guardrails | Content safety policies | |
| Service tiers | Mapped to Bedrock service tiers and latency options |
Legend:
- Supported — Fully compatible with Anthropic API
- Available on Select Models — Check your model's capabilities
- Partial — Supported with limitations
- Unsupported — Not available in this implementation
- Extra Feature — Enhanced capability beyond Anthropic API
Models¶
All models supported by the Bedrock Converse and ConverseStream APIs are supported, plus every model served by Bedrock Mantle when enabled — including OpenAI GPT-5.x, xAI Grok, and Google Gemma 4. Requests to Mantle models are passed through natively or converted automatically depending on the model's upstream API support — see Bedrock Mantle below.
Bedrock Mantle¶
Mantle-only Claude models are passed through to the upstream Anthropic Messages API; other Mantle models are converted to an OpenAI shape (Responses or Chat Completions). Parameter fidelity differs per path:
| Parameter | Claude passthrough | Converted to an OpenAI shape |
|---|---|---|
Server tools (web_search, code_execution, bash, text_editor, computer, …) | Forwarded verbatim (anthropic-beta flags are not auto-injected on the Mantle path — send them in the anthropic-beta header) | Rejected with 400 |
Browser & computer toolsets (browser_toolset_*, computer_toolset_*) | Forwarded verbatim, with the browser_state blocks that answer them | Rejected with 400, browser_state results included |
MCP connector (mcp_servers, mcp_toolset) | Dropped before the request leaves — see MCP Connector | Dropped |
thinking | Forwarded | Dropped on conversion (use output_config.effort for portable reasoning control) |
context_management | Forwarded — see Context Editing | Dropped |
thinking response blocks | Returned as sent upstream | Not returned — a converted model's chain of thought is only available on the OpenAI-compatible APIs |
output_config.effort | Forwarded | Mapped to reasoning effort |
output_config.format | Fails upstream — not supported by the Mantle Messages API | json_schema mapped to OpenAI structured output |
top_k | Forwarded | Dropped |
cache_control markers | Forwarded (prompt caching preserved) | Dropped |
stop_sequences | Forwarded | Dropped when served via the Responses API |
max_tokens | Forwarded as sent, 0 included — a pre-warm call answers with an empty completion; omitted, a gateway default of 4096 is sent, because the upstream API requires the field | Below 16, raised to 16 when served via the Responses API (its minimum; a budget of 0 or 1, sent as a cache pre-warm or a cheap model probe by some clients, would otherwise be rejected with 400) — where the classic endpoint also serves the model (the GPT-5.6 and GPT-6 families, by default), clearing AWS_BEDROCK_MANTLE_PREFERRED_MODELS moves it there, where any budget down to 1 is honored as sent; forwarded unchanged when served via Chat Completions, except 0, which is raised to 1 |
metadata.user_id | Forwarded | Forwarded, SHA-256-hashed when over 64 characters |
service_tier | Forwarded | Only auto is forwarded |
Workspace attribution (anthropic-workspace)
Mantle requests can be attributed to a Bedrock Workspace for cost tracking and observability with the anthropic-workspace: <project-id> header (a bare project ID such as proj_abc123, not an ARN). It is honored per-request only when AWS_BEDROCK_ALLOW_MANTLE_PROJECT_OVERRIDE is true; otherwise the server default (AWS_BEDROCK_MANTLE_PROJECT) applies. This applies only to models served by the Bedrock Mantle endpoint — classic bedrock-runtime models ignore the header.
Claude Models Name Aliases¶
This API supports dynamic model name aliases matching the official Anthropic API. You can use Claude model names exactly as they appear in Anthropic's documentation, and they will be automatically resolved to the corresponding Bedrock model identifiers.
Examples:
claude-opus-5→anthropic.claude-opus-5claude-sonnet-5→anthropic.claude-sonnet-5claude-haiku-4-5-20251001→anthropic.claude-haiku-4-5-20251001-v1:0
For Claude 4 and later, a date-stripped shortcut (e.g. claude-haiku-4-5) is also accepted and resolves to the latest dated variant.
Aliases for non-Anthropic models are also supported as normal.
Wildcard Model Patterns¶
model also accepts a glob pattern — claude-sonnet-*, say — and the server serves the most recently released match. The response's model field always names the concrete model that served the request, streaming and non-streaming alike — never the alias or the pattern the request named.
Working with messages¶
Prompt Caching¶
Reduce costs and improve response times by caching frequently-used prompt components across multiple requests. This feature is particularly effective for applications with consistent system prompts, tool definitions, or conversation contexts.
Supported Models:
- Anthropic Claude: Full support for system, messages, and tools caching
- Amazon Nova: Support for system and messages caching
- Moonshot Kimi K3 and OpenAI GPT-6: Automatic — a repeated prompt prefix is cached without
cache_controland reported inusage.cache_read_input_tokens;cache_controlmarkers are accepted and ignored
Documentation
See Amazon Bedrock Prompt Caching - Supported Models for the complete list of models supporting prompt caching.
Cache Creation Costs
Cache creation incurs a higher cost than regular token processing. Only use prompt caching when you expect a high cache hit ratio across multiple requests with similar prompts.
How to Use:
Add cache_control blocks to the content you want to cache:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic.claude-fable-5",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "You are a helpful assistant with extensive knowledge...",
"cache_control": {"type": "ephemeral"}
}
],
"messages": [
{"role": "user", "content": "What is 2 + 2?"}
]
}'
Granular Cache Control:
Enable caching for specific sections by adding cache_control blocks:
- System messages: Add to system text blocks
- Messages: Add to the last message content block you want cached
- Tools: Add to the last tool definition you want cached (Anthropic Claude only)
{
"model": "anthropic.claude-fable-5",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "System instructions...",
"cache_control": {"type": "ephemeral"}
}
],
"tools": [
{
"name": "get_weather",
"description": "Get weather data",
"input_schema": {...},
"cache_control": {"type": "ephemeral"}
}
],
"messages": [...]
}
Benefits:
- Cost Reduction: Cached tokens are billed at a lower rate than regular input tokens
- Lower Latency: Cached prompts eliminate reprocessing time
- Automatic Management: The API handles cache invalidation and updates
Usage Tracking:
Cached token usage is reported in the response:
{
"usage": {
"input_tokens": 300,
"cache_creation_input_tokens": 1200,
"cache_creation": {
"ephemeral_5m_input_tokens": 1200,
"ephemeral_1h_input_tokens": 0
},
"cache_read_input_tokens": 0,
"output_tokens": 100
}
}
cache_creation splits the same total across the cache entry lifetimes, which are billed at different rates. It is present when a per-TTL split is reported.
In subsequent requests with cache hits:
{
"usage": {
"input_tokens": 300,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 1200,
"output_tokens": 100
}
}
Context Editing¶
An agent loop grows its prompt with every tool result and thinking block it replays. context_management (context editing) clears the oldest of them before the prompt reaches the model, while your client keeps sending the full history.
The request below replays three weather lookups and keeps only the latest result; a real agent would trigger on input_tokens instead, well below its context window:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-haiku-4-5",
"max_tokens": 256,
"tools": [{
"name": "get_weather",
"description": "Get the weather for a city",
"input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}
}],
"messages": [
{"role": "user", "content": "What is the weather in Paris, Lyon and Nice?"},
{"role": "assistant", "content": [{"type": "tool_use", "id": "toolu_01", "name": "get_weather", "input": {"city": "Paris"}}]},
{"role": "user", "content": [{"type": "tool_result", "tool_use_id": "toolu_01", "content": "Paris: sunny, 21 degrees, humidity 55%, wind 12 km/h from the west, UV index 5, sunrise 07:31, sunset 19:52, visibility 10 km, pressure 1016 hPa, no rain expected in the next 48 hours, overnight low 12 degrees, air quality good, pollen count moderate, tomorrow similar with a light breeze in the afternoon and scattered high clouds in the evening"}]},
{"role": "assistant", "content": [{"type": "tool_use", "id": "toolu_02", "name": "get_weather", "input": {"city": "Lyon"}}]},
{"role": "user", "content": [{"type": "tool_result", "tool_use_id": "toolu_02", "content": "Lyon: cloudy, 18 degrees, humidity 55%, wind 12 km/h from the west, UV index 5, sunrise 07:31, sunset 19:52, visibility 10 km, pressure 1016 hPa, no rain expected in the next 48 hours, overnight low 12 degrees, air quality good, pollen count moderate, tomorrow similar with a light breeze in the afternoon and scattered high clouds in the evening"}]},
{"role": "assistant", "content": [{"type": "tool_use", "id": "toolu_03", "name": "get_weather", "input": {"city": "Nice"}}]},
{"role": "user", "content": [{"type": "tool_result", "tool_use_id": "toolu_03", "content": "Nice: sunny, 24 degrees, humidity 55%, wind 12 km/h from the west, UV index 5, sunrise 07:31, sunset 19:52, visibility 10 km, pressure 1016 hPa, no rain expected in the next 48 hours, overnight low 12 degrees, air quality good, pollen count moderate, tomorrow similar with a light breeze in the afternoon and scattered high clouds in the evening"}]}
],
"context_management": {
"edits": [{
"type": "clear_tool_uses_20250919",
"trigger": {"type": "tool_uses", "value": 2},
"keep": {"type": "tool_uses", "value": 1}
}]
}
}'
The two oldest results are cleared before the model sees the prompt, and the response says so:
{
"context_management": {
"applied_edits": [
{"type": "clear_tool_uses_20250919", "cleared_input_tokens": 150, "cleared_tool_uses": 2}
]
}
}
| Edit | Clears | Options |
|---|---|---|
clear_tool_uses_20250919 | The oldest tool results, and optionally the tool inputs | trigger (input_tokens or tool_uses; 100,000 input tokens by default), keep (3 tool uses by default), clear_at_least, exclude_tools, clear_tool_inputs (true or a list of tool names) |
clear_thinking_20251015 | The thinking blocks of older assistant turns | keep: {"type": "thinking_turns", "value": N}, or "all". Must be the first edit, and needs thinking enabled or adaptive |
Behaviour:
- Claude models apply the edits. The
context-management-2025-06-27flag the Anthropic API requires inanthropic-betais added for you, so the header is optional here. - Applied edits are reported in
context_management.applied_edits— with the number of tool uses or thinking turns cleared, and the input tokens saved — and, when streaming, on the finalmessage_deltaevent. The field is present whenever context management is enabled, including when the flag arrives only inanthropic-beta; a model that clears older thinking by default reports that as aclear_thinking_20251015entry you did not ask for.usage.input_tokenscounts the edited prompt, which is what is billed. - Short tool results are left in place, as the Anthropic API does: a reached trigger over one-line results can still report an empty
applied_edits. count_tokenscounts the edited prompt and reports the unedited count incontext_management.original_input_tokens.- Other models accept the field and ignore it: the conversation reaches the model unedited, the response carries no
context_management, and the server log records a warning. Clients such as Claude Code send the field on every turn with thinking on, so refusing it would break them. - Batch results do not report
applied_edits. - Compaction (
compact_20260112) is not available and is refused as an unknown edit type, like any other edit type the API does not define.
System Prompt¶
System prompts define the AI assistant's behavior, personality, and instructions (e.g., "You are a helpful assistant"). Most models support system prompts.
Unsupported Models
Some models don't support system prompts (mistral.mistral-7b-instruct-v0:2, mistral.mixtral-8x7b-instruct-v0:1). By default, stdapi.ai silently drops system messages for these models, allowing cross-model compatibility. To receive errors instead, configure DROP_UNSUPPORTED_SYSTEM_PROMPT=false.
Mid-Conversation System Messages¶
Beyond the top-level system parameter, a message may use the system role to steer the model from a specific point in the conversation onward.
{
"model": "anthropic.claude-opus-5",
"max_tokens": 1024,
"system": "You are a helpful assistant.",
"messages": [
{"role": "user", "content": "Hello."},
{"role": "system", "content": "From now on, answer in one word."},
{"role": "assistant", "content": "Hi."},
{"role": "user", "content": "How are you?"}
]
}
Handling:
- Claude 4.8+, Claude 5+ and later (Opus, Sonnet and Haiku alike), Fable and Mythos (
claude-opus-4-8,claude-sonnet-4-9,claude-opus-5,claude-sonnet-5,claude-haiku-5,claude-fable-5,claude-mythos-*): forwarded natively, so the directive applies from its position in the conversation. - Claude 4.7 and earlier (Opus, Sonnet and Haiku alike) (
claude-opus-4-5,claude-sonnet-4-6,claude-haiku-4-7, and every earlier generation down to Claude 2): the content is appended to thesystemprompt instead, keeping the same request working across every model.
Placement
A directive is forwarded natively only where the model accepts it: between a user turn and an assistant turn, as in the example above. Anywhere else — before the first turn, or right before the final user turn — it is appended to the system prompt instead, where it applies to the whole conversation. Requests therefore never fail because of placement.
S3 Image Support¶
Access images directly from your S3 buckets without generating pre-signed URLs or downloading files locally.
Supported Formats:
- Images: JPEG, PNG, GIF, WebP
How to Use:
Simply reference your S3 images using the s3:// URI scheme in image source fields:
{
"model": "anthropic.claude-fable-5",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image"},
{
"type": "image",
"source": {
"type": "url",
"url": "s3://my-bucket/images/photo.jpg"
}
}
]
}
]
}
IAM Permissions Required
Your API service must have IAM permissions to read from the specified S3 buckets. S3 objects must be in the same AWS region as the executed model or accessible via your IAM role. Standard S3 data transfer and request costs apply.
Benefits:
- No pre-signed URLs - Direct S3 access without generating temporary URLs
- Security - Images stay in your AWS account with IAM-controlled access
- Performance - Optimized data transfer within AWS infrastructure
- Large images - No size limitations of data URIs or base64 encoding
Files API References (file-id:)¶
Image and document content blocks also accept the project-local file-id: URI scheme in their string-overloaded source.url and source.data fields, to reference a file previously uploaded via the Anthropic Files API:
{
"type": "image",
"source": {
"type": "url",
"url": "file-id:file_0190c51c7de7455d9b8c2efe27dfbf67"
}
}
When to use which path
The Anthropic-native {"type": "file", "file_id": "file_…"} source (typed JSON) is unchanged and preferred for new code. The file-id: URI is the equivalent for the string-overloaded source.url / source.data fields, used alongside s3://, https://, and data: URIs. See Files API → Referencing Uploaded Files.
Document Input¶
Send documents as context for the model to analyze and reference. Supports multiple source types:
- Base64 PDF: Inline PDF documents encoded in base64
- URL PDF: PDF documents fetched from HTTP(S) URLs (downloaded server-side)
- Plain text: Raw text content as documents
- Content blocks: Structured content with text and images
Enable citations on document blocks to get precise source references in responses:
{
"type": "document",
"source": {
"type": "text",
"media_type": "text/plain",
"data": "The capital of France is Paris."
},
"title": "Geography",
"citations": {"enabled": true}
}
Citation Support
Citation support varies by model and document format. PDF documents generally have the best citation support across models.
When the response streams, each citation arrives as a citations_delta inside a content_block_delta event and belongs to the text block it is sent on, so a streamed answer carries the same citations as the same request answered in one piece:
{
"type": "content_block_delta",
"index": 0,
"delta": {
"type": "citations_delta",
"citation": {
"type": "char_location",
"cited_text": "The capital of France is Paris.",
"document_index": 0,
"document_title": "Geography",
"start_char_index": 0,
"end_char_index": 31
}
}
}
Server Tools¶
Server tools are built-in capabilities that foundation models can use directly without requiring you to implement backend integrations. Different model providers support different server tools through their native tool formats.
Amazon Nova Tools¶
| Tool | Anthropic Tool Name | Amazon Nova 2 | Amazon Nova Premier (legacy) |
|---|---|---|---|
| Web Grounding | web_search | ||
| Code Interpreter | code_execution |
Web Grounding¶
The Anthropic web_search tool is supported on models that declare web search as a system tool. When you include a web_search tool in your request, it is automatically mapped to the model's native system tool (e.g., nova_grounding for Amazon Nova 2 models).
Usage:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "amazon.nova-2-lite-v1:0",
"messages": [
{"role": "user", "content": "What are the latest news today?"}
],
"tools": [
{"type": "web_search_20250305", "name": "web_search"}
]
}'
Region Compatibility
Web grounding is only available in US Bedrock regions. To ensure all requests are routed to a US region, restrict the model using AWS_BEDROCK_MODEL_REGION_RESTRICT:
export AWS_BEDROCK_MODEL_REGION_RESTRICT='{"amazon.nova-": ["us-east-1"]}'
Limitations:
- No citation text in response blocks: Unlike native Anthropic
web_search, theweb_search_tool_resultcontent block carries only theurlandtitleof each result — nevercited_textorencrypted_index. The cited content itself is reflected only through the text content of the response. - No streamed search metadata: the
server_tool_useblock is streamed as a start event with empty input, so the search terms are not visible while the answer streams. Any citation the model reports is streamed as acitations_deltaevent on the text block it supports. - No search counter in
usage:usage.server_tool_useis always omitted, soweb_search_requestsnever carries a number. Count theserver_tool_useblocks whosenameisweb_searchinstead — each one is a search, answered by aweb_search_tool_resultblock carrying the sametool_use_id. Filter on the name: a model that also runs code emitsserver_tool_useblocks for that too, so counting them all overstates the searches. - No search filtering on non-Claude models: Amazon's
systemToolgrounding has no equivalent forallowed_domains,blocked_domains,max_uses, oruser_location. Requests to a system-tool web search model (e.g. Amazon Nova 2) that set any of these fields are rejected with a400 Bad Requestrather than silently running an unfiltered search. Anthropic Claude models forward these fields natively and are unaffected. - Not served on the OpenAI GPT models: Amazon Bedrock serves their web search on the Bedrock Mantle endpoint alone, and the Messages route reaches them through
bedrock-runtime. Aweb_searchtool sent to one is rejected with a400 Bad Requestnaming the two ways to route the model to Mantle, rather than reaching the model as a function tool it cannot answer.
Model Compatibility
Requesting web_search on a model that does not support it will return a 400 Bad Request error. The OpenAI GPT-5.x family runs web search on the Responses API instead: its results are reported as web_search_call items and url_citation annotations, which have no equivalent in an Anthropic web_search_tool_result block, so this endpoint rejects the tool rather than answering with a different shape.
Code Interpreter¶
Amazon Nova Code Interpreter enables models to securely execute Python code in isolated sandbox environments. Enable it by passing a code_execution tool, which is automatically mapped to the model's native nova_code_interpreter system tool.
Learn More
Usage:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "amazon.nova-2-lite-v1:0",
"messages": [
{"role": "user", "content": "Calculate the first 10 Fibonacci numbers."}
],
"tools": [
{"type": "code_execution_20250522", "name": "code_execution"}
]
}'
Model Compatibility
Requesting code_execution on a model that does not support it will return a 400 Bad Request error.
Anthropic Claude Server Tools¶
Anthropic Claude models support server-side tools that are executed by the model provider. Declare them in their native Anthropic JSON format.
Supported Tools by Model:
| Tool | Claude 3.5 Sonnet v2 | Claude 3.7 – 4.5 | Claude 4.6+ |
|---|---|---|---|
bash | |||
text_editor (str_replace_based_edit_tool or str_replace_editor) | |||
computer | |||
memory |
On Claude 4.6 and later, a bare computer tool is promoted to the newer computer_20251124 tool type.
Usage:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic.claude-sonnet-5",
"max_tokens": 4096,
"messages": [
{"role": "user", "content": "Run a Python script that prints hello world."}
],
"tools": [
{"type": "bash_20250124", "name": "bash"},
{"type": "text_editor_20250728", "name": "str_replace_based_edit_tool"}
]
}'
Beta Headers
Claude server tools require specific anthropic-beta flags on Bedrock. On the classic Bedrock (Converse) path these flags are automatically injected when the corresponding server tools are included in the request — no manual header required (on the Mantle path they are not auto-injected; send them in the anthropic-beta header):
bash,text_editor→computer-use-2024-10-22(Claude 3.5) orcomputer-use-2025-01-24(Claude 3.7+)computer→computer-use-2024-10-22(Claude 3.5),computer-use-2025-01-24(Claude 3.7 – 4.5), orcomputer-use-2025-11-24(Claude 4.6+, tool typecomputer_20251124)memory→context-management-2025-06-27(Claude 3.7+)
You can still pass additional anthropic-beta flags for non-tool beta features (e.g., output-128k-2025-02-19): in the HTTP header on both paths, or in the request body on the classic path. Header flags are added to the ones the gateway injects, never replaced by them, and on both paths a flag outside the allowlist is dropped.
Model Compatibility
Requesting a server tool on a model that does not support it will return a 400 Bad Request error. Non-Claude models do not support these tools.
Unsupported Anthropic Server Tools¶
The following Anthropic server tools are not supported via the classic Bedrock (Converse) path:
code_execution— Code execution sandboxweb_search— Web search (available on Amazon Nova models vianova_grounding; the OpenAI GPT-5.x family offers it on/v1/responsesonly)web_fetch— Web page fetchingtool_search— Tool searchcontainer_upload— Container file upload
Requests using these tools on Converse-served Claude models will return a 400 Bad Request error. On Mantle-served Claude models (passthrough), server tools are instead forwarded verbatim to the upstream Messages API, which decides support; when a Mantle request must be converted to an OpenAI shape, server tools are rejected with 400.
Browser and Computer Toolsets¶
A toolset declares a whole tool family in a single tools entry — browser_toolset_20260801 and computer_toolset_20260801 are the current ones. The entry carries no name and no input_schema: only its type, an optional cache_control, and a configs map keyed by member name (screenshot, navigate, zoom, …) whose entries take enabled and defer_loading. A member left out of configs keeps the toolset's own default for it.
{
"tools": [
{
"type": "browser_toolset_20260801",
"configs": {"javascript_exec": {"enabled": false}}
}
]
}
The whole shape validates, on POST /v1/messages, on POST /v1/messages/count_tokens and in a batch request alike:
toolset_nameontool_useandtool_resultblocks — the family a member's call belongs to — is preserved, so a replayed toolset turn stays paired.browser_stateparts inside atool_result— the tab inventory, plus thetab_opened,download_started,download_completedanddownload_failedstate changes — are accepted with every field the Anthropic API defines.
Where they run. A Mantle-served Claude model is the only path that can serve them, and the gateway does not decide whether it does: the toolset and the browser_state results answering it are forwarded verbatim, and the upstream Messages API answers. A model that does not offer the toolset answers 400 itself, naming the tool types it does offer. Whether any Mantle-served model currently accepts the 2026 toolset types has not been confirmed here, so treat that path as forwarding rather than as support. Everywhere else — Converse-served models, and a Mantle model whose request is converted to an OpenAI shape — the request is refused with 400 naming the toolset, because a model answering without the browser or the desktop answers a different question. A replayed browser_state result is refused the same way on those paths, rather than being reduced to an empty tool result.
A dated toolset type newer than the two above is accepted and takes the same path, so a client tracking the API ahead of this page is never refused for its version alone.
The web-access setting does not govern them
AWS_BEDROCK_EXTERNAL_WEB_ACCESS applies to the Bedrock built-in web search alone, so it neither allows nor refuses a toolset: on the Mantle Claude passthrough a browser toolset is forwarded whatever it is set to, and any caller may ask the model to drive a browser against the pages it names. A deployment that must keep that boundary has to turn AWS_BEDROCK_MANTLE_ENABLED off, which is what leaves no path serving them.
MCP Connector¶
Anthropic's MCP connector — mcp_servers plus mcp_toolset entries in tools — asks the model to act as an MCP client and call a remote MCP server while it answers. That is not supported here: the models this API serves do not open those connections.
Rather than reject an otherwise valid request, the gateway accepts it and ignores the connector:
mcp_serversand everymcp_toolsetentry are dropped; no connection is made and none of the server's tools can be called. Anauthorization_tokenyou supply is never forwarded to any backend, and never reaches the logs: not therequest_paramsfield (LOG_REQUEST_PARAMS), and not the report of a request rejected as malformed, which names the fields that failed and none of their values.- Every other tool in
toolsis kept and behaves normally. Acache_controlbreakpoint carried by anmcp_toolsetis dropped with it, so a request that marked its cache prefix there caches a shorter prefix than intended — put the breakpoint on a tool that survives. - A
tool_choiceis dropped when the toolsets were the only entries intools: the choice had nothing left to select from, and forcing a tool against an emptytoolsarray is refused by the Messages API. mcp_tool_useandmcp_tool_resultblocks already in the conversation — what a client records from a connector-enabled turn elsewhere, both inside the assistant turn that ran the tool — are accepted and read as an ordinary tool call and its result, so a replayed transcript keeps its meaning. Should the model call that tool again, it comes back as a normaltool_useblock for you to run.
To use MCP tools with this API, run the MCP client yourself: connect to the server, declare its tools in tools, and return each result as a tool_result block.
Two different MCP roles
This gateway is itself an MCP server: an AI agent can call its endpoints as MCP tools, which is the opposite direction from the connector described above. See MCP (Model Context Protocol).
Provider-Specific Parameters¶
Unlock advanced model capabilities by passing provider-specific parameters directly in your requests. These parameters are forwarded to Bedrock and allow you to access features unique to each foundation model provider.
Documentation
See Bedrock Model Parameters for the complete list of available parameters per model.
How It Works:
Add provider-specific fields at the top level of your request body alongside standard Anthropic parameters. The API automatically forwards these to the appropriate model provider via Bedrock.
Configuration Options:
Option 1: Per-Request
Add provider-specific parameters directly in your request body.
Option 2: Server-Wide Defaults
Configure default parameters for specific models via the DEFAULT_MODEL_PARAMS environment variable:
export DEFAULT_MODEL_PARAMS='{
"anthropic.claude-sonnet-4-5-20250929-v1:0": {
"anthropic_beta": ["output-128k-2025-02-19"]
}
}'
Parameter Priority
Per-request parameters override server-wide defaults.
Behavior:
- Compatible parameters: Forwarded to the model and applied
- Unsupported parameters: Return HTTP 400 with an error message
- Reserved names:
model_idandadditional_request_fieldscollide with the gateway's own request-building parameters and are rejected with a400 invalid_request_errornaming the key, instead of being forwarded
Anthropic Claude Features¶
Enable cutting-edge Claude capabilities including extended thinking and reasoning.
Extended Thinking¶
Enable extended thinking with the first-class thinking request parameter, just like the official Anthropic API — no beta header is required:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic.claude-sonnet-5",
"max_tokens": 2048,
"thinking": {"type": "adaptive", "display": "summarized"},
"messages": [{"role":"user","content":"Solve a complex problem"}]
}'
thinking accepts {"type": "enabled", "budget_tokens": <n>} (the budget must be less than max_tokens), {"type": "disabled"}, {"type": "adaptive"}, or {"type": "between_tools"}. Alternatively, control reasoning depth with output_config.effort (low, medium, high, xhigh, max). An effort alone turns thinking on; beside disabled or between_tools, thinking stays off and the effort only sets how much the answer spends.
Turning Thinking Off on Claude Sonnet 5.5
Claude Sonnet 5.5 rejects disabled; its lowest setting is between_tools: no thinking before the answer, only short progress updates between tool calls, returned as summarized thinking blocks and billed as output tokens. It takes no other field, and an effort above high returns a 400. The gateway sends thinking turned off to Sonnet 5.5 and later as between_tools, whichever route asked for it: disabled here, reasoning_effort: "none" or enable_thinking: false on Chat Completions, reasoning.effort: "none" on Responses, think: false on Ollama. On any other model, where upstream returns a 400, between_tools is served as disabled is: thinking turned off, or the adaptive default with a warning on the models that always reason.
display on an enabled or adaptive configuration chooses what the thinking blocks carry: summarized returns a summary of the reasoning, omitted returns empty thinking fields with their signature. Claude Opus 4.7 and later, Sonnet 5, Fable and Mythos omit the text by default, so set "display": "summarized" to read their reasoning; earlier Claude models summarize by default. The thinking tokens are billed the same either way. Other models accept the field and ignore it. The beta updates value is not available and is refused with a 400, with or without its beta header; use summarized or omitted.
On models whose reasoning depth is an effort level rather than a token budget (Amazon Nova 2, DeepSeek V3), budget_tokens turns reasoning on and the depth follows that model's own scale. Set output_config.effort to choose it.
A small max_tokens turns reasoning off on Converse-served Claude 3.7–4.5
Thinking tokens are spent out of the output limit, and Converse takes no budget below 1,024 tokens nor one that is not smaller than max_tokens. An effort level asked for alongside a max_tokens of 1,024 or less therefore leaves no budget to derive, and the request is served without reasoning rather than refused — a warning is logged. Raise max_tokens above 1,024 to get reasoning back.
Disabled Thinking Not Honored on Claude Opus 5.5+, Fable, Mythos, OpenAI GPT-6 Astra, GPT-6.1+ and gpt-oss
These models always reason. The request is accepted and a warning is recorded in the request log, but the disabled configuration is dropped and the model's default reasoning is used (adaptive mode on Claude): the response may still carry thinking blocks, and their output tokens are still billed. An output_config.effort sent alongside still applies, so use it to lower the depth.
Response with Thinking:
When extended thinking is enabled, the response includes thinking content blocks:
{
"id": "msg_abc123",
"type": "message",
"role": "assistant",
"content": [
{
"type": "thinking",
"thinking": "Let me think about this step by step..."
},
{
"type": "text",
"text": "Here's the solution..."
}
],
"usage": {...}
}
Server-Wide Configuration
You can also configure default model parameters server-wide using the DEFAULT_MODEL_PARAMS environment variable (see Provider-Specific Parameters).
Unsupported Beta Flags
Unsupported flags that would change output return HTTP 400 errors.
Documentation
See Using Claude on Amazon Bedrock for more details on Claude-specific parameters.
Model-Specific Features¶
TwelveLabs Pegasus¶
twelvelabs.pegasus-1-2-v1:0 is a video-understanding model. Because Pegasus accepts exactly one video and one text prompt per call, this API adapts the conversation automatically:
- The latest video found anywhere in the conversation (any role, any position) is forwarded as the video input.
- The latest contiguous run of user text (back to the previous assistant or tool turn) is concatenated and forwarded as the text prompt.
temperatureandmax_tokensare forwarded.
Silently ignored (no error): system prompts, tools, top_p, stop sequences, and prompt caching.
Upstream format limitation: The Anthropic Messages API does not define a video content block in its stable spec. To stay fully compatible with standard Anthropic clients, pass the video as an image content block with media_type set to the video MIME type (e.g. video/mp4) — the server detects the video MIME type automatically and routes it to Pegasus correctly.
Video input formats: data:video/mp4;base64,…, https://…, s3://bucket/key, or file-id:…. Videos above 18.75 MB are automatically uploaded to S3.
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "twelvelabs.pegasus-1-2-v1:0",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "url", "url": "s3://my-bucket/video.mp4"}
},
{"type": "text", "text": "Describe what happens in this video."}
]
}
]
}'
Limits and behaviour to know¶
inference_geo is accepted and ignored. The gateway routes to the Bedrock regions the deployment configures in AWS_BEDROCK_REGIONS, so a per-request geography cannot change where inference runs. A request that sets it is answered normally, from the configured regions; set the regions to pin data residency.
container is accepted and ignored, in both forms. The identifier string and the object carrying id and skills — the form Agent Skills requests use — both validate and both change nothing: no container is created, reused or returned, no skill is loaded, and the response carries no container object. A request naming skills is answered by the model on its own, so an answer that depends on a skill's instructions will differ from what the Anthropic API returns.
max_tokens is optional. The Anthropic API requires it; here the model's own default output limit applies when the field is absent, so a client that relies on the 400 for a missing field gets an answer instead.
max_tokens: 0 warms the prompt cache, and comes back with one token. The Anthropic API answers a zero budget with an empty completion. Here the request is accepted and the prompt is processed and written to the cache the same way, but the reply carries a single token instead of none, with stop_reason max_tokens. Budget the pre-warm call for that one output token; a negative budget is still rejected with 400. Bedrock Mantle models vary — the Claude passthrough honors the zero exactly, and answers with nothing. A pre-warm asks for no output, so what would describe output is refused with 400 — the same refusal, and the same message, the Anthropic API gives: "stream": true, a tool_choice of "tool" or "any" ("auto" is served), and output_config.format.
max_tokens is capped when only it overflows the context window. An input the window holds alone but not beside max_tokens is answered with the output limited to what the window leaves, and an answer that fills that room stops with stop_reason model_context_window_exceeded. Writer Palmyra and Google Gemma refuse such an input with 400 input length and `max_tokens` exceed context limit. A streamed request is served, or refused, the same way, before its stream starts. A max_tokens filling the window on its own is refused with a plain 400 asking to lower it.
Token counting past the context window is approximate. POST /v1/messages/count_tokens counts an input larger than the model's context window, as the Anthropic API does, and the answer is always above the window, so a client counting to learn whether a conversation still fits learns that it does not. On a model counted exactly, the figure past the window can differ slightly from the Anthropic API's: on Claude Haiku 4.5, a 300,000-token message came within 20 tokens of it, and a 300,000-token tool conversation within 0.4%.
Server tools are counted at their definition's usual size. A request offering web_search, web_fetch, code_execution, tool_search_tool_bm25 or tool_search_tool_regex is counted with the tool's definition at the size the Anthropic API gives it on Claude 4.5 and 4.6 models: a fixed size per tool version, whatever the prompt. An unknown version counts as the latest known one. A history replaying a server tool's calls, results and web search citations is counted too; the pages behind web search results are only known in encrypted form, so a count holding search results can differ from the Anthropic API's by a few percent (within 2% on Claude Haiku 4.5).
Token counting is exact for Claude up to 4.6, and an approximation that errs high elsewhere. POST /v1/messages/count_tokens answers for every text model, and the Claude models served by Bedrock Mantle are counted exactly too. What each approximation guarantees, and how far above the exact count it typically lands, is under Exact and approximate counts; the usage a response reports is always exact.
The official SDK no longer sends the sampling parameters. anthropic ≥ 1.0 removed temperature, top_p and top_k from messages.create(). The gateway still accepts all three on the wire and older clients keep working; with the current SDK, pass them as extra_body={"temperature": …}.
The MCP connector never opens a connection. mcp_servers and mcp_toolset entries are dropped before the request leaves — declare the tools in tools and run them yourself. See MCP Connector for what happens to tool_choice and to an authorization_token.
A server tool a model cannot run is refused, not silently dropped. web_search, code_execution and the Claude computer-use tools answer 400 on a model without support for them, and the Mantle-to-OpenAI conversion path rejects server tools outright — see Server Tools and Bedrock Mantle. The same holds for the browser and computer toolsets and for a replayed browser_state result: outside the models that run them, both answer 400 naming what is unavailable — see Toolsets.
Some models get their system prompt dropped. Models with no system-prompt support (mistral.mistral-7b-instruct-v0:2, mistral.mixtral-8x7b-instruct-v0:1) have system messages removed so the same request works across models; set DROP_UNSUPPORTED_SYSTEM_PROMPT=false to get an error instead.
Request headers¶
This endpoint supports standard Bedrock headers for enhanced control over your requests. All headers are optional and can be combined as needed.
Content Safety (Guardrails)¶
| Header | Purpose | Valid Values |
|---|---|---|
X-Amzn-Bedrock-GuardrailIdentifier | Guardrail ID for content filtering | Your guardrail identifier |
X-Amzn-Bedrock-GuardrailVersion | Guardrail version | Version number (e.g., 1) |
X-Amzn-Bedrock-Trace | Guardrail trace level | disabled, enabled, enabled_full |
Performance Optimization¶
| Header | Purpose | Valid Values |
|---|---|---|
X-Amzn-Bedrock-Service-Tier | Service tier selection | default, flex, priority, reserved |
X-Amzn-Bedrock-PerformanceConfig-Latency | Latency optimization | standard, optimized |
Model-Specific Headers¶
| Header | Purpose | Valid Values | Models |
|---|---|---|---|
anthropic-beta | Enable Anthropic beta features | Comma-separated feature names (e.g., computer-use-2025-01-24,context-management-2025-06-27) | Anthropic Claude |
Example with all headers:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-H "X-Amzn-Bedrock-GuardrailIdentifier: your-guardrail-id" \
-H "X-Amzn-Bedrock-GuardrailVersion: 1" \
-H "X-Amzn-Bedrock-Trace: enabled" \
-H "X-Amzn-Bedrock-Service-Tier: priority" \
-H "X-Amzn-Bedrock-PerformanceConfig-Latency: optimized" \
-d '{
"model": "anthropic.claude-fable-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello!"}]
}'
Detailed Documentation
For complete information about these headers, configuration options, and use cases, see:
Try it¶
Basic message:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "amazon.nova-micro-v1:0",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Say hello world"}]
}'
Streaming response:
curl -N -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "amazon.nova-micro-v1:0",
"max_tokens": 1024,
"stream": true,
"messages": [{"role": "user", "content": "Write a haiku about the sea."}]
}'
Multi-modal with image:
{
"model": "amazon.nova-2-lite-v1:0",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image"},
{
"type": "image",
"source": {
"type": "url",
"url": "https://example.com/photo.jpg"
}
}
]
}
]
}
With tool calling:
curl -X POST "$BASE/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic.claude-fable-5",
"max_tokens": 1024,
"tools": [
{
"name": "get_weather",
"description": "Get weather information",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
},
"required": ["location"]
}
}
],
"messages": [
{"role": "user", "content": "What is the weather in Paris?"}
]
}'
Count tokens (without sending a message):
curl -X POST "$BASE/v1/messages/count_tokens" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic.claude-haiku-4-5-20251001-v1:0",
"messages": [{"role": "user", "content": "Hello, how are you?"}]
}'
Response:
{"input_tokens": 29}
Counted Request
The count follows the request anthropic_message would send for the same body: thinking/output_config.effort, cache_control breakpoints and mid-conversation system message placement are taken into account. Server tools, documents, and models without an exact count are counted as Limits and behaviour to know describes.
Next steps¶
Next: Models API · Search Models API · Files API · Message Batches API · Configuration