Skip to main content
The rewrite endpoint lets you keep your existing SDK (OpenAI, Anthropic, Google, or Bedrock) and point it at a different provider. Lava translates request and response formats so your code stays unchanged while the underlying model and billing go through Lava.
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 caseEndpoint
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}
With forward, you send the provider’s native format. With rewrite, you send your SDK’s format and Lava converts to/from the provider’s format.

URL Format

POST https://api.lava.so/v1/rewrite/{clientFormat}/{providerUrl}
  • clientFormat — The format your SDK sends and expects: openai | anthropic | google | bedrock
  • providerUrl — The provider base URL and path (same style as forward), e.g. api.openai.com/v1/chat/completions or api.anthropic.com/v1/messages
Your SDK’s base URL is the full rewrite URL including the provider path. The SDK appends its own path (e.g. /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 formatSDK appendsLava strips this suffix
openai/v1/chat/completionsThat suffix; the path you put in the URL is what the provider sees
anthropic/v1/messagesThat suffix
googleVaries 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
bedrockVaries (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
So for OpenAI SDK → Anthropic you set base URL to: 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:
StepWhat happens
SDK sendshttps://api.lava.so/v1/rewrite/openai/api.anthropic.com/v1/messages/v1/chat/completions (base URL + SDK suffix)
Lava stripsThe trailing /v1/chat/completions (OpenAI SDK’s fixed path)
Lava calls providerhttps://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 set apiKey)
  • Google-style: x-goog-api-key: <forward_token> or key query param — for Google-format clients when using the rewrite endpoint with a Google SDK
Your Lava token (forward token or secret key) is passed through; no change from the forward flow.

Using the OpenAI SDK

With the official openai 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.
  1. Install the SDK (if needed): npm install openai
  2. Create the client with Lava’s rewrite URL as baseURL and your Lava token as apiKey.
  3. Call the API as you normally would — use the provider’s model name (e.g. claude-haiku-4-5 when targeting Anthropic, or us.amazon.nova-lite-v1:0 for Bedrock).
The 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.
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://api.lava.so/v1/rewrite/openai/api.anthropic.com/v1/messages',
  apiKey: process.env.LAVA_FORWARD_TOKEN  // or your Lava secret key
});

const completion = await client.chat.completions.create({
  model: 'claude-haiku-4-5',
  max_tokens: 256,
  messages: [{ role: 'user', content: 'Hello!' }]
});
Streaming works the same: pass 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.
  1. Install the SDK (if needed): npm install @anthropic-ai/sdk
  2. Create the client with Lava’s rewrite URL as baseURL and your Lava token as apiKey. Use x-api-key style (the Anthropic SDK sends it by default when you set apiKey).
  3. Call the API with client.messages.create() as usual. Use the provider’s model name (e.g. gpt-4o-mini when targeting OpenAI).
The Anthropic SDK appends /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.
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  baseURL: 'https://api.lava.so/v1/rewrite/anthropic/api.openai.com/v1/chat/completions',
  apiKey: process.env.LAVA_FORWARD_TOKEN
});

const message = await client.messages.create({
  model: 'gpt-4o-mini',
  max_tokens: 256,
  messages: [{ role: 'user', content: 'Hello!' }]
});
For streaming, set stream: true in messages.create(). Tool use, system prompts, and image blocks are translated to the target provider where supported.

Streaming

Set stream: 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:
X-Lava-Input-Format: openai | anthropic | google | bedrock

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, responseMimeType for Google).
  • response_format: { type: "json_schema", json_schema: { ... } } (OpenAI) is mapped to Anthropic’s output_config, Google’s responseSchema, or Bedrock’s system prompt as appropriate.
You can send OpenAI-style 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_url or 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

StatusCauseRetryable
401Invalid or malformed token, or wrong auth headerNo — check credentials and use Bearer or x-api-key
402Insufficient credit balanceNo — add funds first
400Invalid clientFormat, unsupported translation, or malformed bodyNo — check URL path and request body
429Rate limit exceededYes — back off and retry
500/502/503Provider or Lava server errorYes — retry with backoff
Provider error responses are translated back into your SDK’s format when possible.

Troubleshooting

Verify your Lava token (forward token or secret key), ensure the correct header (Authorization: Bearer or x-api-key) is set, and try the forward token from Gateway > Secrets to isolate the issue.
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.
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.

Next Steps