AWS Bedrock
An llm · client with dialect: aws-bedrock sends requests to Amazon Bedrock Runtime. Applications keep using the OpenAI or Anthropic SDK: Zilla Plus converts each request for Bedrock, signs it with AWS Signature Version 4, and returns the reply in the caller's API. An llm · server can also accept requests in the Bedrock Converse API.
Configuration
bedrock_llm_client:
type: llm
kind: client
options:
dialect: aws-bedrock
server: https://bedrock-runtime.us-east-1.amazonaws.com
telemetry:
metrics:
- llm.*
exit: bedrock_http_client
bedrock_http_client:
type: http
kind: client
exit: bedrock_tls_client
bedrock_tls_client:
type: tls
kind: client
options:
sni:
- bedrock-runtime.us-east-1.amazonaws.com
exit: bedrock_tcp_client
bedrock_tcp_client:
type: tcp
kind: client
options:
host: bedrock-runtime.us-east-1.amazonaws.com
port: 443Unlike the OpenAI and Anthropic clients, an aws-bedrock client doesn't connect through sys:http_client. It exits to its own http · client, tls · client, and tcp · client. To use another region, change the host in all three places: server, sni, and host.
Route Bedrock model IDs to it from llm · proxy:
north_llm_proxy:
type: llm
kind: proxy
routes:
- when:
- model:
- anthropic.*
- amazon.*
- us.anthropic.*
- us.amazon.*
exit: bedrock_llm_clientMany Bedrock models are called through a cross-region inference profile, whose ID starts with a geography such as us., for example us.anthropic.claude-haiku-4-5-20251001-v1:0. Add patterns for the profile IDs your callers use.
How Requests Are Sent
Zilla Plus picks the Bedrock API for each request from the API the caller used and the model it asked for:
| Caller's API | Model | Bedrock API |
|---|---|---|
| Anthropic | anthropic.*, with or without a geography prefix such as us.anthropic.* | InvokeModel, with the request in Anthropic's own format |
| OpenAI | openai.* | InvokeModel, with the request in OpenAI's own format |
| OpenAI or Anthropic | Any other model | Converse, converted from the caller's API |
| Bedrock Converse | Any model | Converse |
- InvokeModel sends the caller's request to
/model/{modelId}/invoke, or/model/{modelId}/invoke-with-response-streamfor a streaming request, and returns the model's reply as it is. Zilla Plus removes themodelandstreammembers and adds theanthropic_versionthat Anthropic models require. Foropenai.*models, the reasoning the model returns between<reasoning>tags is removed from the reply. - Converse sends the request to
/model/{modelId}/converse. A streaming request converted from the OpenAI or Anthropic API is also sent to/converse, and the reply is streamed back in the caller's format. Only a caller that uses the Bedrock Converse API itself is sent to/converse-stream.
Model in the Path
Zilla Plus puts each request's model in the Bedrock request path, so one client serves every Bedrock model routed to it. A path in the server URL is ignored.
What Is Converted
When a request is converted to the Converse API, each part of the conversation is converted to its Converse form:
| Section | Converse |
|---|---|
| System instruction | system[].text |
| User and assistant text, refusals | text |
| Images and documents sent inline | image and document, with bytes |
| Audio sent inline, from the OpenAI API | audio, with bytes |
| Reasoning, from the Anthropic API | reasoningContent |
| Tool definitions | toolConfig.tools[].toolSpec |
| Tool calls | toolUse |
| Tool results | toolResult |
The output token limit is carried across as inferenceConfig.maxTokens. Other request settings aren't carried across, as with any translation.
Some content can't be converted:
- Images and documents sent by URL, and tool definitions for tools the provider runs, are rejected with
400 Bad Request, naming the section, such asuser-image cannot be converted from openai to aws-bedrock. - Server tool results and citations are skipped.
- Video, audio, and Amazon S3 references in a Bedrock Converse request can't be sent to OpenAI or Anthropic, and are rejected with
400 Bad Request. - Members only Bedrock has, such as
guardrailConfig,cachePoint, andadditionalModelRequestFields, are kept when the caller uses the Bedrock Converse API, and dropped otherwise.
Credentials
Zilla Plus signs every request itself, so options.authorization is not used with aws-bedrock. It takes credentials from the standard AWS default credentials chain:
- The
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY, andAWS_SESSION_TOKENenvironment variables - An EKS pod's IAM role (IRSA), an ECS task role, or an EC2 instance profile
The identity needs the bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream permissions on the models callers ask for. When no credentials are available, requests fail with 503 Service Unavailable and the message AWS credentials are not available.
Region
The signing region comes from the server host, such as us-east-1 for https://bedrock-runtime.us-east-1.amazonaws.com. When the host doesn't contain a region, for example a VPC endpoint, Zilla Plus uses the AWS default region chain, such as the AWS_REGION environment variable.
Accepting the Bedrock Converse API
An llm · server with dialect: aws-bedrock, or with no dialect, also accepts requests in the Bedrock Converse API: POST /model/{modelId}/converse and POST /model/{modelId}/converse-stream. The model is taken from the path, so llm · proxy routes these requests like any other, to Bedrock or to another provider, and the reply comes back as Converse JSON or as a Converse event stream.
north_llm_server:
type: llm
kind: server
options:
dialect: aws-bedrock
exit: north_llm_proxyWhen the server has options.authorization, the request's Authorization header is checked against the guard with the credentials template, and a rejected request gets 403 with the error type UnrecognizedClientException. Zilla Plus doesn't verify AWS Signature Version 4 on incoming requests.
Errors are returned in the Bedrock format, with the error type in the x-amzn-errortype header and a {"message": ...} body:
| Status | Error type |
|---|---|
400 | ValidationException |
401, 403 | AccessDeniedException |
404 | ResourceNotFoundException |
408 | ModelTimeoutException |
429 | ThrottlingException |
503 | ServiceUnavailableException |
Other 4xx | ValidationException |
Other 5xx | InternalServerException |
A request to any other path, including InvokeModel, gets 404 with the error type NotFoundException, and a request whose content type isn't JSON gets 415 with UnsupportedMediaTypeException.
Limits
- A request must fit in one of Zilla's buffer slots, 32 KiB by default. Each event of a reply streamed from Bedrock must also fit in a buffer slot.
- Bedrock doesn't report reasoning tokens.
Next Steps
- OpenAI Apps on AWS Bedrock: serve OpenAI applications from Bedrock.
- llm · client: the full
llm · clientreference.

