Migrate from OpenAI
This guide moves an app that calls the OpenAI API directly over to Glexir. Glexir is OpenAI-compatible for text generation, embeddings and speech-to-text, so most apps only change their key and base URL. The steps below also cover the features Glexir does not support and the state that does not carry over.
The short version
If you would rather keep the openai package, set its apiKey and baseURL instead. See Use any OpenAI SDK.
Step by step
Create a key and add credit
Sign up at app.glexir.com, create an API key on the API keys page, and add credit on the Billing page. Glexir is prepaid: requests are refused with 402 credit_balance_exhausted when your balance can't cover them.
Usage is billed at OpenAI's list price. Larger single top-ups add bonus credit. See Pricing for the tiers and Credits & billing for how balances work.
Create one key per environment, for example staging and production. See Best practices.
Check that your models are sold
Glexir sells text, embedding and speech-to-text models that have a price in its price book. List them:
Use the model alias (gpt-5.4-mini), not a dated snapshot name (gpt-5.4-mini-2026-03-17). Snapshot names return 403 model_not_priced. Responses may still report the snapshot name in model; that is expected and is billed at the alias's price.
Point your client at Glexir
Replace your OpenAI key with your Glexir key. @glexir/sdk calls https://api.glexir.com/v1 by default. With the openai package, also set the base URL to https://api.glexir.com/v1.
Switching to @glexir/sdk is a small change, because its resources and method names match the OpenAI SDK for every endpoint Glexir supports:
| OpenAI SDK | @glexir/sdk |
|---|---|
import OpenAI from "openai" | import Glexir from "@glexir/sdk" |
new OpenAI({ apiKey, baseURL }) | new Glexir({ apiKey }) |
OPENAI_API_KEY, OPENAI_BASE_URL | GLEXIR_API_KEY, GLEXIR_BASE_URL |
OpenAI.APIError, OpenAI.RateLimitError, ... | APIError, RateLimitError, ... (named exports) |
@glexir/sdk sends an Idempotency-Key on every non-GET request, so its automatic retries are never billed twice. With the openai package you send that header yourself.
Remove unsupported features
Glexir rejects some OpenAI features before the request goes upstream. You are not charged for rejected requests. The full list is in What Glexir rejects. The usual changes:
- Hosted tools. Replace web search, file search, code interpreter, MCP and similar tools with
functionorcustomtools that your code runs. - Prompt templates. Replace
prompt: { id: "pmpt_..." }with the text ininstructions. - Audio in chat. Send audio to
/v1/audio/transcriptionsfirst, then pass the text to the model.
Recreate stored state
Objects you created on OpenAI do not exist on Glexir. Requests that reference them return 404.
- Files. Upload them again through Glexir, with
purpose: "user_data"(model input) orpurpose: "batch". - Stored responses and conversations. Start new ones.
previous_response_idandconversationonly accept IDs created through Glexir. - Stored chat completions. Only completions created through Glexir with
store: trueare listed. - Batches. Submit new batches from input files uploaded through Glexir.
If you keep conversation state yourself (sending the full history, or store: false and replaying output items), nothing changes.
Handle Glexir-specific errors
Add handling for the statuses OpenAI does not return in the same way:
- 402
credit_balance_exhaustedorspend_limit_exceeded: alert someone and stop retrying. - 429
concurrency_limit_exceeded: limit how many requests you run at once. - 409 and 422 with
idempotency_*codes: see Idempotency.
See HTTP error codes.
Test and switch over
Run your test suite against Glexir with a staging key. Compare outputs and token usage with your OpenAI baseline, then switch production. Watch the Usage page in the dashboard for the first days.
What Glexir rejects
Endpoints
These return 404 unknown_endpoint:
- Image generation and editing (
/v1/images/...) - Text-to-speech (
/v1/audio/speech), realtime and voice - Video
- Moderations
- Fine-tuning
- Vector stores, Assistants and Threads
- Uploads (multipart large-file uploads)
- Containers, evals and the legacy
/v1/completionsendpoint - OpenAI organization and admin endpoints. Use the Glexir dashboard for keys, usage and billing.
Supported endpoints are Responses, Conversations, Chat Completions, Embeddings, audio transcriptions and translations, Files, Batches and Models.
Request features
| Feature | Where | Error |
|---|---|---|
OpenAI-hosted tools (any tool type other than function, custom or a namespace of those) | tools, tool_choice, allowed_tools, additional_tools input items | 400 unsupported_on_glexir |
Input items produced by hosted tools, such as web_search_call, file_search_call, code_interpreter_call, computer_call, mcp_call, shell_call, apply_patch_call, image_generation_call | Responses input, conversation items | 400 unsupported_on_glexir |
Audio input (input_audio content parts) | Responses and Chat Completions | 400 unsupported_on_glexir |
Audio output (audio, modalities: ["audio"]) and assistant audio messages | Chat Completions | 400 unsupported_on_glexir |
web_search_options | Chat Completions | 400 unsupported_on_glexir |
Dashboard prompt templates (prompt) | Responses | 400 unsupported_on_glexir |
| Image, video, realtime, TTS, moderation and fine-tuned models | Any endpoint | 400 model_not_found |
Models that only work on the Responses API (names with -pro, and similar) | Chat Completions | 400 model_not_found |
| Models without a Glexir price, including dated snapshot names | Any endpoint | 403 model_not_priced |
A service_tier your account tier does not allow | Responses, Chat Completions | 403 tier_not_allowed |
Files and batches
purposemust beuser_data(up to 50 MB) orbatch(up to 20 MB).- Batch input must be a
.jsonlfile uploaded through Glexir. Each line is checked against the same rules as a live request. - A batch uses one model and one endpoint (
/v1/responses,/v1/chat/completionsor/v1/embeddings), has at most 50,000 requests, and can't stream or reference stored responses, conversations or reasoning items. completion_windowmust be24h.
Behaviour that changes
safety_identifieranduserare replaced with an identifier derived from your organization and the value you sent. Keep sending a per-end-user value.prompt_cache_keyis namespaced to your organization.- OpenAI webhooks are not forwarded. Poll background responses and batches.
- Rate limits and spend limits are Glexir's, not OpenAI's. See Rate limits & spend limits.