Migrate from OpenAI
SovereignEG's API is OpenAI-compatible for chat completions, embeddings, image generation and model listing. For those, migration means changing your API key and base URL and choosing a model from the catalog. Other OpenAI APIs (Responses, Assistants, Files, Batches, Audio, fine-tuning, image edits and the legacy /v1/completions) are not available.
Step 1: Change the base URL
Python
# Before (OpenAI)
from openai import OpenAI
client = OpenAI(api_key="sk-openai-...")
# After (SovereignEG) — one line changed
from openai import OpenAI
client = OpenAI(
api_key="sk-...",
base_url="https://backend.sovereigneg.com/v1"
)Node.js
// Before (OpenAI)
const client = new OpenAI({ apiKey: 'sk-openai-...' });
// After (SovereignEG) — one line added
const client = new OpenAI({
apiKey: 'sk-...',
baseURL: 'https://backend.sovereigneg.com/v1',
});curl
# Before
curl https://api.openai.com/v1/chat/completions ...
# After — just change the URL
curl https://backend.sovereigneg.com/v1/chat/completions ...Step 2: Map your models
Some OpenAI models are listed under their usual OpenAI ids — check the Model Library or GET /v1/models for the exact id (an id that isn't listed returns 400 model_not_found). For anything not listed, find a live equivalent:
| Your OpenAI habit | What to do on SovereignEG |
|---|---|
| Fast/cheap (GPT-3.5 class) | Sort catalog by input price; pick the cheapest live chat model |
| High quality (GPT-4 class) | Try a larger live chat model; benchmark on your prompts |
| Long context (GPT-4 Turbo class) | Sort by context window; pick a live model that fits your docs |
| Arabic workloads | Shortlist live chat models from multilingual families (search the Model Library, e.g. "Qwen") and test them on your Arabic prompts — see the Arabic & MENA guide |
| Embeddings | Use a live embed model — separate endpoint from chat |
Step 3: Check the differences
Chat completions, streaming (SSE), tool calling, system messages, multi-turn conversations, temperature / top_p / max_tokens and stop sequences use OpenAI's request and response format. Watch for these differences:
- Streaming: token usage is always reported, so every stream ends with a chunk whose
choiceslist is empty. Checkchoicesbefore readingchoices[0]. - Legacy function calling: the deprecated top-level
functions/function_callparameters are not supported; usetools/tool_choice. - Sampling on Claude Opus 4.7 and later: these Claude models accept only their default sampling, so
temperatureandtop_pare not sent to them while Anthropic serves the request. The request still succeeds, and theX-Dropped-Paramsresponse header names what was left out (see Chat Completions). - Moderation:
/v1/moderationsis a basic keyword check, not an AI moderation model. Itsmodelfield readssovereigneg-basic-keyword-check. Keep your own moderation step for production content. - Errors: the JSON error object has the same shape (plus
request_id), but some status codes differ, so check how your code branches on them: running out of credit or hitting a spend cap returns 402 (typeinsufficient_quota; OpenAI uses 429), an unknown model returns 400model_not_found(OpenAI uses 404), and a body that fails schema validation returns 422invalid_request_body(OpenAI uses 400). A 429 retried inside the 60-second window is counted and rejected again, so stop sending for at least theRetry-Aftertime instead of relying on the SDK's automatic retries. See Errors.
Environment variable approach
The cleanest migration uses environment variables:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["LLM_API_KEY"],
base_url=os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1")
)# Switch providers by changing env vars — no code change
LLM_API_KEY=sk-...
LLM_BASE_URL=https://backend.sovereigneg.com/v1What's different
| Feature | OpenAI | SovereignEG |
|---|---|---|
| Latency from MENA | Provider dependent | Provider dependent on the selected model/backing |
| Billing currency | USD only | EGP |
| Data location | US/EU by default | Standard routing today; contact us for Egypt-hosted deployments |
| Arabic models | OpenAI's multilingual models | OpenAI models plus other multilingual model families in the Model Library |
| Pricing | USD | EGP prepaid credits |
LangChain migration
If you're using LangChain, it's the same one-line change:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-oss-20b",
api_key="sk-...",
base_url="https://backend.sovereigneg.com/v1"
)LangChain chains and agents that use ChatOpenAI with tool calling (bind_tools) work with this change, on models that support tool calling. Not supported: the Responses API (use_responses_api=True or OpenAI built-in tools; the endpoint returns 404), the legacy functions parameter used by create_openai_functions_agent and bind_functions (it is ignored, so the model never sees those functions), and wrappers for OpenAI's Assistants, audio and files APIs.