Unlike the forward endpoint, Lava does translate request and response bodies on rewrite. You send your SDK’s format (e.g. OpenAI
messages + model); Lava converts to the provider’s format and back. The provider never sees your SDK’s schema.Prerequisites: You need a Lava secret key (same auth as the forward proxy). Use your secret key directly or a forward token for customer billing. Pass via
Authorization: Bearer or x-api-key.When to Use Rewrite vs Forward
| Use case | Endpoint |
|---|---|
| Your SDK and provider match (e.g. OpenAI SDK → OpenAI API) | Forward: POST /v1/forward?u=<provider_url> |
| Your SDK and provider differ (e.g. Anthropic SDK → OpenAI, OpenAI SDK → Bedrock) | Rewrite: POST /v1/rewrite/{clientFormat}/{providerUrl} |
URL Format
clientFormat— The format your SDK sends and expects:openai|anthropic|google|bedrockproviderUrl— The provider base URL and path (same style as forward), e.g.api.openai.com/v1/chat/completionsorapi.anthropic.com/v1/messages
/v1/chat/completions); Lava strips that suffix and forwards to the provider path you put in the URL.
Authentication
Same as the forward endpoint — pass your Lava secret key or forward token. When using the OpenAI, Anthropic, or Google SDKs, setapiKey to your Lava token and the SDK sends the right header automatically.
Examples
The simplest way to use the rewrite endpoint — passformat to gateway() and Lava handles URL construction and token generation. Omit format to use the forward endpoint (no translation).
- SDK
- cURL
Using the OpenAI SDK
With the officialopenai npm package, you use the rewrite endpoint by setting baseURL and apiKey when creating the client. No other code changes are needed — all client.chat.completions.create() calls go through Lava, and Lava translates to the provider you put in the URL.
- Install the SDK (if needed):
npm install openai - Create the client with Lava’s rewrite URL as
baseURLand your Lava token asapiKey. - Call the API as you normally would — use the provider’s model name (e.g.
claude-haiku-4-5when targeting Anthropic, orus.amazon.nova-lite-v1:0for Bedrock).
baseURL must be the full rewrite path for the provider you want. The OpenAI SDK appends /v1/chat/completions; Lava strips that and forwards to the path in your URL.
To call OpenAI with the OpenAI SDK, use the forward endpoint — the format already matches, so rewrite is unnecessary.
- Call Claude (Anthropic)
- Call Bedrock (e.g. Nova)
- Call Gemini (Google)
stream: true in the request. Tools, response_format, and image content are translated automatically when the provider supports them.
Using the Anthropic (Claude) SDK
With the official@anthropic-ai/sdk package, you set baseURL and apiKey when creating the Anthropic client. The SDK sends Anthropic-format requests; Lava translates them to the provider in the URL (OpenAI, Bedrock, Google, etc.) and back to Anthropic format in the response.
- Install the SDK (if needed):
npm install @anthropic-ai/sdk - Create the client with Lava’s rewrite URL as
baseURLand your Lava token asapiKey. Use x-api-key style (the Anthropic SDK sends it by default when you setapiKey). - Call the API with
client.messages.create()as usual. Use the provider’s model name (e.g.gpt-4o-miniwhen targeting OpenAI).
/v1/messages to the base URL. Your baseURL must include the full provider path so that after Lava strips /v1/messages, the remaining path is the correct provider endpoint.
To call Anthropic (Claude) with the Anthropic SDK, use the forward endpoint — the format already matches, so rewrite is unnecessary.
- Call GPT (OpenAI)
- Call Bedrock (e.g. Nova)
- Call Gemini (Google)
stream: true in messages.create(). Tool use, system prompts, and image blocks are translated to the target provider where supported.
Streaming
Setstream: true (or the provider’s equivalent) in the request body. Lava streams responses back in your SDK’s format (e.g. OpenAI SSE or Anthropic SSE). Bedrock: pointing at /converse with stream: true automatically uses /converse-stream on the provider side. Google: for streaming, use the stream endpoint in the path (e.g. .../gemini-2.5-flash:streamGenerateContent instead of :generateContent).
Input Format Override
The endpoint infers the client format from the URL path. If you need to override (e.g. custom client), set:Structured Output (JSON / JSON Schema)
Lava translates structured-output options across providers:response_format: { type: "json_object" }(OpenAI) is mapped to provider-specific mechanisms (e.g. system prompt for Anthropic/Bedrock,responseMimeTypefor Google).response_format: { type: "json_schema", json_schema: { ... } }(OpenAI) is mapped to Anthropic’soutput_config, Google’sresponseSchema, or Bedrock’s system prompt as appropriate.
response_format when using the OpenAI SDK against Anthropic or Google and get valid structured responses.
Images
- URLs: For providers that require base64 (Anthropic, Google, Bedrock), Lava fetches image URLs and converts them to the format the provider expects.
- Data URLs (
data:image/...;base64,...) work without fetching. - Anthropic base64 image blocks are converted to OpenAI-style
image_urlor data URLs when the provider is OpenAI.
Tool Calls
Tool definitions and tool-call/tool-result messages are translated between OpenAI, Anthropic, Google, and Bedrock formats. Use your SDK’s normal tool schema; Lava maps to the provider’s format.Model Fallbacks
The rewrite endpoint supports automatic failover to a different provider or model when the primary request fails. Pass a fallback chain in thex-lava-fallbacks request header as a JSON array of {url, model} objects:
- A 5xx server error (500, 502, 503, etc.)
- 429 rate limiting
- A network-level failure (connection refused, timeout, etc.)
model: "gpt-4o". No request translation is needed since the fallback also accepts OpenAI format.
Multi-hop chain — chain multiple fallbacks for maximum resilience:
| Error code | Status | Cause |
|---|---|---|
rewrite_fallback_header_invalid | 400 | x-lava-fallbacks is present but not a valid JSON array of {url, model} objects |
rewrite_fallback_unmanaged_key | 400 | Fallbacks requested but auth uses an unmanaged provider key |
Error Handling
| Status | Cause | Retryable |
|---|---|---|
| 401 | Invalid or malformed token, or wrong auth header | No — check credentials and use Bearer or x-api-key |
| 402 | Insufficient credit balance | No — add funds first |
| 400 | Invalid clientFormat, unsupported translation, or malformed body | No — check URL path and request body |
| 429 | Rate limit exceeded | Yes — back off and retry |
| 500/502/503 | Provider or Lava server error | Yes — retry with backoff |
Troubleshooting
401 Unauthorized
401 Unauthorized
400 or wrong response format
400 or wrong response format
Check that the URL path uses the correct
clientFormat (openai, anthropic, google, bedrock) and that the provider path matches the provider you intend to call. The request body must be in your SDK’s format — Lava translates it to the provider.CORS errors in browser
CORS errors in browser
Lava blocks frontend requests to prevent token exposure. Always call Lava from your backend:
Frontend → Your Backend → Lava → AI Provider.How does path stripping work?
How does path stripping work?
When using the OpenAI or Anthropic SDK with
Example: OpenAI SDK → Anthropic with
baseURL, the SDK appends its own path (e.g. /v1/chat/completions or /v1/messages). Lava automatically strips these suffixes so the provider sees the correct endpoint.| Client format | SDK appends | Lava strips |
|---|---|---|
openai | /v1/chat/completions | That suffix |
anthropic | /v1/messages | That suffix |
google | Varies (no fixed suffix) | Nothing — put the full provider path in the URL |
bedrock | Varies (/converse, /invoke) | When using OpenAI/Anthropic SDK → Bedrock, Lava strips the SDK suffix as above |
baseURL set to https://api.lava.so/v1/rewrite/openai/api.anthropic.com/v1/messages:- SDK sends:
.../api.anthropic.com/v1/messages/v1/chat/completions - Lava strips:
/v1/chat/completions - Provider receives:
https://api.anthropic.com/v1/messages
lava.gateway({ format }), you don’t need to think about this at all.Fallback: Query Parameter
You can still use the?u= style as a fallback:
POST /v1/rewrite?u=<encoded_provider_url>
The URL does not include clientFormat, so you must send the X-Lava-Input-Format header (openai, anthropic, google, or bedrock) so Lava knows how to interpret the request body. The body and headers must be in your client’s SDK format (e.g. OpenAI or Anthropic), not the provider’s; Lava will translate to the provider. The path-based form above is preferred for SDK base URLs.
Next Steps
Forward Proxy
When your SDK and provider match, use the forward endpoint
Supported Providers
List of providers you can route through Lava