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 forward token (same as the forward proxy). Use your secret key or a generated forward token with
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.
Client Formats and Path Stripping
Each SDK appends a fixed path:| Client format | SDK appends | Lava strips this suffix |
|---|---|---|
openai | /v1/chat/completions | That suffix; the path you put in the URL is what the provider sees |
anthropic | /v1/messages | That suffix |
google | Varies by method (no single fixed suffix) | Nothing; put the full provider path in the URL and the Google SDK does not append a standard path |
bedrock | Varies (e.g. /converse, /invoke) | With the Bedrock native SDK (clientFormat=bedrock), path is method-specific — no single suffix. With OpenAI or Anthropic SDK calling Bedrock, Lava strips /v1/chat/completions or /v1/messages as above |
https://api.lava.so/v1/rewrite/openai/api.anthropic.com/v1/messages
The OpenAI client will call this base + /v1/chat/completions. Lava strips that suffix and forwards to the provider:
| Step | What happens |
|---|---|
| SDK sends | https://api.lava.so/v1/rewrite/openai/api.anthropic.com/v1/messages/v1/chat/completions (base URL + SDK suffix) |
| Lava strips | The trailing /v1/chat/completions (OpenAI SDK’s fixed path) |
| Lava calls provider | https://api.anthropic.com/v1/messages |
Authentication
Use the same auth as the forward endpoint:- Bearer token:
Authorization: Bearer <forward_token>(OpenAI SDK and most clients) - Anthropic-style:
x-api-key: <forward_token>(Anthropic SDK sends this when you setapiKey) - Google-style:
x-goog-api-key: <forward_token>orkeyquery param — for Google-format clients when using the rewrite endpoint with a Google SDK
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.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.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.