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 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 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.

Authentication

Same as the forward endpoint — pass your Lava secret key or forward token. When using the OpenAI, Anthropic, or Google SDKs, set apiKey to your Lava token and the SDK sends the right header automatically.

Examples

The simplest way to use the rewrite endpoint — pass format to gateway() and Lava handles URL construction and token generation. Omit format to use the forward endpoint (no translation).
import { Lava } from ‘@lavapayments/nodejs’;

const lava = new Lava();

// Send OpenAI-format requests to Claude
const data = await lava.gateway(‘https://api.anthropic.com/v1/messages’, {
  format: ‘openai’,
  body: {
    model:claude-haiku-4-5’,
    messages: [{ role:user’, content:Hello!’ }],
  },
});

// With customer billing
const billed = await lava.gateway(‘https://api.anthropic.com/v1/messages’, {
  format: ‘openai’,
  body: {
    model:claude-haiku-4-5’,
    messages: [{ role:user’, content:Hello!’ }],
  },
  customer_id: ‘conn_xyz789’,
  meter_slug: ‘my-meter’,
});

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 fromopenai’;

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.

Model Fallbacks

The rewrite endpoint supports automatic failover to a different provider or model when the primary request fails. Pass a fallback chain in the x-lava-fallbacks request header as a JSON array of {url, model} objects:
x-lava-fallbacks: [{"url":"api.openai.com/v1/chat/completions","model":"gpt-4o"}]
Each entry specifies a scheme-less provider URL (same format as the rewrite path) and the model to use at that provider. Entries are tried in order — the first successful response wins. Trigger conditions — a fallback attempt is made when the primary provider returns:
  • A 5xx server error (500, 502, 503, etc.)
  • 429 rate limiting
  • A network-level failure (connection refused, timeout, etc.)
Client errors (400, 401, 402, 403, 404) do not trigger fallback. Cross-provider failover — fallbacks can cross provider formats. For example, if your primary is Claude (Anthropic format) and your fallback is GPT (OpenAI format), Lava re-translates the original request body into the fallback provider’s format automatically. Example: Claude primary with GPT fallback
curl -X POST ‘https://api.lava.so/v1/rewrite/openai/api.anthropic.com/v1/messages’ \
  -H ‘Content-Type: application/json’ \
  -H ‘Authorization: Bearer $LAVA_FORWARD_TOKEN \
  -H ‘x-lava-fallbacks: [{"url":"api.openai.com/v1/chat/completions","model":"gpt-4o"}]’ \
  -d ‘{
    "model": "claude-haiku-4-5",
    "messages": [{ "role": "user", "content": "Hello!" }]
  }’
If Anthropic returns 5xx or 429, Lava retries the request against OpenAI with model: "gpt-4o". No request translation is needed since the fallback also accepts OpenAI format. Multi-hop chain — chain multiple fallbacks for maximum resilience:
x-lava-fallbacks: [
  {"url":"api.anthropic.com/v1/messages","model":"claude-haiku-4-5"},
  {"url":"generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent","model":"gemini-2.5-flash"}
]
Unmanaged provider keys are not supported with fallbacks. If you pass a provider API key directly in the request, Lava returns a 400 rewrite_fallback_unmanaged_key error. Fallbacks require Lava-managed credentials so Lava can authenticate against any fallback provider. Use a Lava secret key or forward token instead.
Error codeStatusCause
rewrite_fallback_header_invalid400x-lava-fallbacks is present but not a valid JSON array of {url, model} objects
rewrite_fallback_unmanaged_key400Fallbacks requested but auth uses an unmanaged provider key

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.
When using the OpenAI or Anthropic SDK 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 formatSDK appendsLava strips
openai/v1/chat/completionsThat suffix
anthropic/v1/messagesThat suffix
googleVaries (no fixed suffix)Nothing — put the full provider path in the URL
bedrockVaries (/converse, /invoke)When using OpenAI/Anthropic SDK → Bedrock, Lava strips the SDK suffix as above
Example: OpenAI SDK → Anthropic with baseURL set to https://api.lava.so/v1/rewrite/openai/api.anthropic.com/v1/messages:
  1. SDK sends: .../api.anthropic.com/v1/messages/v1/chat/completions
  2. Lava strips: /v1/chat/completions
  3. Provider receives: https://api.anthropic.com/v1/messages
This is handled automatically — if you use 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