GlexirDocs
Dashboard

Guides

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

TypeScript
import Glexir from "@glexir/sdk";

// Before: new OpenAI({ apiKey: process.env.OPENAI_API_KEY })
const glexir = new Glexir({ apiKey: process.env.GLEXIR_API_KEY });

const response = await glexir.responses.create({
  model: "gpt-5.4-mini",
  input: "Write a one-line release note.",
});
console.log(response.output_text);

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:

import Glexir from "@glexir/sdk";

const glexir = new Glexir({ apiKey: process.env.GLEXIR_API_KEY });

for await (const model of glexir.models.list()) {
  console.log(model.id);
}

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_URLGLEXIR_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 function or custom tools that your code runs.
  • Prompt templates. Replace prompt: { id: "pmpt_..." } with the text in instructions.
  • Audio in chat. Send audio to /v1/audio/transcriptions first, 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) or purpose: "batch".
  • Stored responses and conversations. Start new ones. previous_response_id and conversation only accept IDs created through Glexir.
  • Stored chat completions. Only completions created through Glexir with store: true are 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_exhausted or spend_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/completions endpoint
  • 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

FeatureWhereError
OpenAI-hosted tools (any tool type other than function, custom or a namespace of those)tools, tool_choice, allowed_tools, additional_tools input items400 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_callResponses input, conversation items400 unsupported_on_glexir
Audio input (input_audio content parts)Responses and Chat Completions400 unsupported_on_glexir
Audio output (audio, modalities: ["audio"]) and assistant audio messagesChat Completions400 unsupported_on_glexir
web_search_optionsChat Completions400 unsupported_on_glexir
Dashboard prompt templates (prompt)Responses400 unsupported_on_glexir
Image, video, realtime, TTS, moderation and fine-tuned modelsAny endpoint400 model_not_found
Models that only work on the Responses API (names with -pro, and similar)Chat Completions400 model_not_found
Models without a Glexir price, including dated snapshot namesAny endpoint403 model_not_priced
A service_tier your account tier does not allowResponses, Chat Completions403 tier_not_allowed

Files and batches

  • purpose must be user_data (up to 50 MB) or batch (up to 20 MB).
  • Batch input must be a .jsonl file 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/completions or /v1/embeddings), has at most 50,000 requests, and can't stream or reference stored responses, conversations or reasoning items.
  • completion_window must be 24h.

Behaviour that changes

  • safety_identifier and user are replaced with an identifier derived from your organization and the value you sent. Keep sending a per-end-user value.
  • prompt_cache_key is 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.