Published October 15, 2026 · 7 min read
OpenAI-Compatible API Migration Checklist
Move existing OpenAI SDK code to an OpenAI-compatible API without a rewrite: base URL, API key, model names, streaming, errors and billing checks, step by step.
An OpenAI-compatible API accepts the same requests as the OpenAI API and returns the same response shapes. That is what makes a migration cheap: your SDK, prompts, tool definitions and parsing code stay as they are. What changes is where requests go, which key authenticates them and which model names you ask for.
This guide walks through a migration to zcloud as a concrete example, but the checklist applies to any OpenAI-compatible provider.
1. Inventory what your code actually calls
Before you change anything, list the endpoints and features you use. Search your codebase for SDK calls and raw HTTP requests, then note:
- Endpoints — chat completions, the Responses API, embeddings, images, audio, files, batch.
- Features — streaming, tool calling, structured output, vision input, prompt caching.
- Models — every model name hard-coded in config, environment variables or code.
Compatibility is per endpoint. zcloud serves POST /v1/chat/completions, POST /v1/responses and GET /v1/models in the OpenAI format, plus POST /v1/messages in the Anthropic format, all on one API key. If you depend on an endpoint a provider does not list, keep that traffic where it is.
2. Change the base URL and the key
The official OpenAI SDKs for Python and Node read two environment variables, so many projects can migrate without touching code:
OPENAI_BASE_URL=https://api.zrouter.dev/v1
OPENAI_API_KEY=zr_your_key_here
If your code constructs the client explicitly, pass the same values:
from openai import OpenAI
client = OpenAI(base_url="https://api.zrouter.dev/v1", api_key="zr_your_key_here")
Note the /v1 suffix: OpenAI-format clients expect it in the base URL. Anthropic SDKs are the exception — they take the root URL (https://api.zrouter.dev) and append /v1/messages themselves. Keys are created in the dashboard and shown once, so store them in a secret manager, not in source control.
3. Map model names
This is the step most migrations get wrong. Model names are provider-specific: the name your code sends must match the provider's catalog exactly. Fetch the list your key can use:
curl https://api.zrouter.dev/v1/models \
-H "Authorization: Bearer $OPENAI_API_KEY"
Then replace each hard-coded name with the matching entry. Keep model names in configuration rather than code, so the next change is a config edit. The public model catalog shows the same names with their prices.
4. Re-test streaming and tool calls
Streaming uses server-sent events in the same format as the original API, so SDK streaming helpers keep working. Still, run your real streaming paths end to end: check that the final chunk arrives, that usage is reported where you read it, and that client cancellation stops the request.
For tool calling and structured output, replay a handful of real production requests against the new endpoint and diff the parsed results. The same request shape does not guarantee every model behaves identically, especially if you also changed the model.
5. Update error handling
Compatible APIs reuse the OpenAI error envelope, but providers add their own codes. On zcloud the ones to handle explicitly are:
401 invalid_api_key— wrong, revoked or expired key. Do not retry.402 insufficient_balance— no Token Plan allowance or PAYG balance for the request. Retrying will not help; top up first.404 model_not_found— the model name is not in the catalog.429and5xx— transient; retry with exponential backoff and jitter.
The full table is in the error reference.
6. Check billing before you cut over
Know how you will be charged before production traffic arrives. On zcloud, a request is charged after it succeeds, at the model's per-token rate. If you hold a Token Plan for that model, its allowance is used first and the PAYG balance covers the rest. Send a few test requests, then confirm the recorded usage in the dashboard matches what you expect. The pricing page shows each model's rate next to the official list price.
7. Roll out gradually
Route a small share of traffic to the new base URL first — a feature flag or a per-environment variable is enough. Compare latency, error rate and output quality against your existing provider for a few days, then move the rest. Keep the old configuration available so rolling back is a one-line change.
Migration checklist
- Endpoints and features you use are all served by the new provider.
OPENAI_BASE_URLends in/v1; the key is stored as a secret.- Every model name matches
GET /v1/modelsexactly. - Streaming, tool calls and structured output pass replay tests.
401,402,404and retryable errors are handled.- Test usage in the dashboard matches your cost estimate.
- Rollback is a configuration change.
For the full endpoint reference and copy-paste examples, see the OpenAI-compatible API quickstart. To estimate what the move saves, follow how to estimate LLM API cost.
FAQ
Do I need to rewrite my code? Usually not. If you use an official OpenAI SDK, changing the base URL, the API key and the model names is typically enough.
Can I use the Anthropic SDK with the same key? Yes. zcloud serves the Anthropic messages endpoint on the same key; point the Anthropic SDK at the root URL without /v1.
What happens when my balance runs out? The API returns 402 insufficient_balance and the request is not run, so nothing is charged for it.