Add a second OpenAI-compatible provider without breaking your app.

Most teams that call an LLM API end up wanting a second provider eventually. The reasons are ordinary: a cost line that grows faster than usage, latency that shows up in the product, or the discomfort of one vendor sitting on the critical path. This playbook is the migration path we would hand a team, written so you can finish it in an afternoon.

1. Why a second provider

Three honest reasons, in order of how often they matter: cost per unit of work, latency where the user feels it, and the ability to fail over. None of these requires abandoning your current provider. A second OpenAI-compatible endpoint sits behind the same client you already use, which is what makes this migration cheap.

2. The 30-minute wiring

If your client speaks the OpenAI API, the change is mostly configuration:

  • Point a second client at a different base_url.
  • Swap the model id.
  • Read the key from the environment, never from source.
  • Put the new path behind a feature flag so you can turn it off without a deploy.

Three differences bite in practice:

  • Streaming. Confirm the chunk shape and the end-of-stream sentinel against your parser before you ship. Test with a long completion.
  • Errors. Map the provider's error body to your own error types at the boundary, so the rest of your code never sees a vendor-specific shape.
  • Token accounting. Read the usage object from the response rather than estimating. Billing follows the provider's count, not yours.

3. Runnable examples

cURL:

curl https://webwright.ai/v1/chat/completions \
  -H "Authorization: Bearer $WEBWRIGHT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"wren-r1","messages":[{"role":"user","content":"Say hello."}]}'

Python with the OpenAI SDK, using the base_url override:

from openai import OpenAI

client = OpenAI(base_url="https://webwright.ai/v1", api_key=WREN_API_KEY)

resp = client.chat.completions.create(
    model="wren-r1",
    messages=[{"role": "user", "content": "Say hello."}],
)
print(resp.choices[0].message.content)

Node:

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://webwright.ai/v1", apiKey: process.env.WREN_API_KEY });

const resp = await client.chat.completions.create({
  model: "wren-r1",
  messages: [{ role: "user", content: "Say hello." }],
});
console.log(resp.choices[0].message.content);

Transcription uses the same client:

curl https://webwright.ai/v1/audio/transcriptions \
  -H "Authorization: Bearer $WEBWRIGHT_API_KEY" \
  -F "file=@meeting.mp3" \
  -F "model=whisper-large-v3-turbo"

For a worked setup in two developer tools, see using WebWright with Cline and OpenCode.

4. A cost model you can trust

Cost per request is tokens times price per token. Keep input and output separate, because they are priced differently.

TierCache / 1MInput / 1MOutput / 1M
Standard$0.10$0.40$1.60
Premium$0.20$0.80$3.20

Multiply your observed monthly input and output tokens by the rates above. For a quick estimate, use the live cost calculator. Transcription is billed by audio duration on the Premium pay-as-you-go tier, so model it per minute of audio, not per token.

5. The evaluation harness

Run the same prompt set against both providers and record three columns: a quality score, p50 and p95 latency, and cost. Quality is the one you cannot automate away, so use a small rubric and score blind. Do not trust a vendor's published benchmark for your workload, including ours. The point of the harness is to replace a claim with your own measurement.

6. Common pitfalls

  • Context limits. Confirm the context length for the exact model you call before you send a long document.
  • Retries and idempotency. Retrying a streaming request can duplicate work. Decide what is safe to retry.
  • Audio billing. Transcription is billed by duration, so a silent or padded file still costs.
  • Trial terms. The trial converts to Hobby after four days or when its assigned token budgets are exceeded, whichever comes first. Normal signup requires a payment method; the magic-link path creates an account without one, and the same conversion applies, with access blocked after conversion until a payment method is added and a successful charge is made.

7. When to book a consult

If you would rather not pick the first use case alone, that is what the consult is for. One working session maps where you are, what you have tried, and what good would look like, and you leave with a prioritized first use case, an architecture, a rough cost, and the honest risks.

The WebWright Team