Migrating from OpenAI
Two-line code change to point an existing OpenAI integration at Bastion.
Bastion's HTTP surface is OpenAI-compatible for chat.completions, completions, embeddings, images.generations, audio.transcriptions, and models. The OpenAI Node, Python, and Go SDKs all work unchanged — point them at Bastion's baseURL and use a Bastion API key.
Step 1: swap baseURL and key
import OpenAI from "openai";
const client = new OpenAI({
- baseURL: "https://api.openai.com/v1",
- apiKey: process.env.OPENAI_API_KEY,
+ baseURL: "https://api.qubittron.ai/v1",
+ apiKey: process.env.QUBITTRON_API_KEY,
}); from openai import OpenAI
client = OpenAI(
- base_url="https://api.openai.com/v1",
- api_key=os.environ["OPENAI_API_KEY"],
+ base_url="https://api.qubittron.ai/v1",
+ api_key=os.environ["QUBITTRON_API_KEY"],
)That's it for the SDK. Existing calls to chat.completions.create, embeddings.create, etc. all keep working.
Step 2: swap model ids
OpenAI model ids (gpt-4o, gpt-4-turbo, text-embedding-3-small, etc.) do not exist on Bastion. Pick a Bastion model in the same class — these are categorical matches, not feature-for-feature equivalents. Confirm per-row parity (tool calling, vision input format, structured output, etc.) against the API reference before swapping in production.
| Use case | OpenAI default | Bastion model in the same class |
|---|---|---|
| General-purpose chat | gpt-4o, gpt-4-turbo | gpt-oss-120b |
| Cost-sensitive chat | gpt-4o-mini | gpt-oss-20b, Llama-3.1-8B-Instruct |
| Long-context chat | gpt-4-turbo | Meta-Llama-3_3-70B-Instruct |
| Coding | gpt-4o | Qwen3-Coder-30B-A3B-Instruct |
| Vision | gpt-4o (vision) | Qwen2.5-VL-72B-Instruct |
| Embeddings | text-embedding-3-small | bge-m3 (see /v1/embeddings) |
Call GET /v1/models for the live list on your account — model availability evolves.
Caveats
These are the cases where "drop-in compatible" needs a footnote.
responses requires store: false
The /v1/responses endpoint is stateless. You must pass store: false (or it will reject the request). If your OpenAI code relied on server-side conversation state, move that state to your own database.
TTS lives at a different path
OpenAI's TTS lives at /v1/audio/speech. Bastion's TTS endpoint follows NVIDIA Riva's contract at /api/v1/tts/text_to_audio — see the TTS page. The OpenAI SDK's audio.speech.create will not work; call fetch directly.
Pass-through, not parity, on advanced fields
Unknown fields (tools, tool_choice, response_format, parallel_tool_calls, etc.) pass through unchanged to the upstream model. If the upstream model doesn't implement that field, you may get a 502 upstream_error. Confirm tool/structured-output support per model before relying on it in production.
HTTPS only, no redirect
Bastion's HTTP→HTTPS redirect strips the Authorization header for security. Always call https://. If you have any code constructing http://api.qubittron.ai/..., fix it before deploying.
Step 3: keep your retry and observability code
The error envelope is OpenAI-compatible (error.message, error.type, error.code). Status codes (401, 429, 5xx, etc.) carry the same semantics. Existing retry middleware, rate-limit handling, and logging should keep working without changes. See Errors and retries if you want to revisit your defaults.
Step 4: rotate keys
Don't reuse the same key across dev, staging, and prod. Issue distinct keys in the dashboard before you swap your environment variables — see API key management.