Migrating from OpenAI

Change the URL, key, and model; verify compatibility and keep a rollback path.

Keep the OpenAI SDK and migrate one Chat Completions request by changing the base URL, key, and model ID. This changes the model producing the answer; it does not make DeepSeek behave like GPT-4o.

 client = OpenAI(
-    base_url="https://api.openai.com/v1",
-    api_key=os.environ["OPENAI_API_KEY"],
+    base_url="https://api.deepraxis.com/openai/v1",
+    api_key=os.environ["PRAXIS_API_KEY"],
 )
-model = "gpt-4o"
+model = "deepseek-flash"

1. Prepare

You need Python 3.10+, uv, and a Praxis key. Create one in Console → API Keys and securely inject it into the current terminal as PRAXIS_API_KEY. Never put the key in code or logs. Keep your original service configuration and key for rollback. Run the commands below in Bash on macOS or Linux.

test -n "${PRAXIS_API_KEY:-}"

Expected: exit code 0. Exit code 1 means the variable is missing; set it before continuing.

2. Choose a model ID

These are migration choices, not aliases or promises of equivalent quality. Availability was checked on October 12, 2026; confirm it in the model catalog before switching traffic.

Existing IDPraxis choiceWhat changes
gpt-4o, gpt-4o-minideepseek-flashThese original IDs do not exist; reassess prompts, tools, and output quality
gpt-4.1, o3-mini, gpt-5deepseek-flashNo automatic mapping; the original IDs return 404
An OpenAI-family model is requiredgpt-5.6-solChat Completions is available; Responses is not
Existing Responses codedeepseek-flash or glm-5.3-flashThese are the currently available Responses choices

For Responses, check that your selected ID appears in GET /openai/v1/models?api=responses (Python: client.models.list(extra_query={"api": "responses"})). Alternatively, inspect supported_apis in GET /model/v1/models or GET /model/v1/models/{id} and confirm it includes openai.responses. Other OpenAI filters are chat, embeddings, images, audio, and videos; comma-separated values match any selected API.

Behavior differences

  • A protocol-compatible request keeps its protocol when forwarded. This does not guarantee every official model, endpoint, or field is available.
  • A listed model can still reject a particular operation with 404 model_protocol_not_offered. Keep Chat and Responses capability checks separate.
  • Recheck streaming, tool execution, structured output, and reasoning on your own prompts before shifting traffic. Field differences live in Chat Completions and Responses.
  • Files, conversations, and response IDs from the original service do not move with a URL change. Retain source data and rebuild the resources your application needs.
  • Chat's usage.cost is the amount charged; Responses and Messages currently omit it. When X-Praxis-Generation-Id is present, use GET /model/v1/generation?id=GENERATION_ID as described in the generation record API. Records may take a few seconds to appear. If the header is absent, check Console → Usage and costs. Neither the response body's id nor X-Request-Id is a substitute for a generation ID. Missing cost does not mean zero cost.

Unsupported endpoints and alternatives

Paths below are relative to /openai/v1 and return 404. Alternatives are not equivalent replacements. If your application depends on these operations, split the calls and keep the original service.

Original endpointMigration option
moderationsNo direct replacement; keep your moderation service
batchesSend individual requests with application-controlled concurrency
fine_tuningChoose an existing model; retain your fine-tuning workflow
assistantsRebuild with Responses / Conversations and an application tool loop
completionsUse chat/completions with messages
audio/translationsTranscribe first, then translate through chat
uploadsUse files; check size and purpose limits
images/variationsSubmit the image and editing instructions to images/edits; evaluate the result

Available endpoints include chat/completions, responses, embeddings, images/generations, images/edits, audio/speech, audio/transcriptions, videos, files, and models. Endpoint availability does not mean every model supports that capability. See the OpenAI API reference for individual operations and limits.

3. Verify one request

Run this complete example after setting PRAXIS_API_KEY:

unset HTTP_PROXY HTTPS_PROXY ALL_PROXY http_proxy https_proxy all_proxy
uv run -q --no-project --with openai --with anthropic python - <<'PY'
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.deepraxis.com/openai/v1",
    api_key=os.environ["PRAXIS_API_KEY"],
    timeout=90.0,
    max_retries=0,
)
models = client.models.list(extra_query={"api": "chat"})
assert "deepseek-flash" in {m.id for m in models.data}
raw = client.chat.completions.with_raw_response.create(
    model="deepseek-flash",
    messages=[{"role": "user", "content": "Reply OK."}],
    max_tokens=1024,
)
reply = raw.parse()
text = reply.choices[0].message.content
print("HTTP", raw.status_code)
print("X-Request-Id:", raw.headers.get("x-request-id"))
print("X-Praxis-Generation-Id:", raw.headers.get("x-praxis-generation-id"))
print(text)
assert raw.status_code == 200 and text and text.strip()
assert raw.headers.get("x-request-id")
PY

Expected: exit code 0, HTTP 200, nonempty text (usually OK.), and an X-Request-Id. Assertions check both model availability and a real reply, not just connectivity. Keep the request ID for troubleshooting, never the key. The example incurs a small usage charge.

Failures

Observed errorAction
404 with Model "gpt-4o" does not exist.Change the model as well as the URL and key; use the exact catalog ID
404 model_protocol_not_offeredUse a model that offers the requested operation; for Responses choose deepseek-flash or glm-5.3-flash
404 Not Found on an endpoint aboveUse its alternative or leave that request on the original service

4. Roll back

Restore all three original values: https://api.openai.com/v1, the key from OPENAI_API_KEY, and your original model ID. Remove Praxis-only request fields and restore original resource IDs. Restart the application so its client uses the restored configuration, then run your original smoke test. Keep its request ID.

Expected: the original endpoint returns a successful response with usable text. Rolling back configuration does not refund calls already made or copy conversation state between services.

API reference → · Compatibility guide →

Export

On this page