Guides
Migrate from OpenAI
Same SDK, same request shapes, the migration is two constructor arguments, a model-name map, and a short list of differences to check.
Swap the credentials
Keep your OpenAI SDK and change what the constructor points at (create the key on the API Keys page first):
import os
from openai import OpenAI
# Before
# client = OpenAI() # reads OPENAI_API_KEY, talks to api.openai.com
# After, same SDK, two constructor arguments
client = OpenAI(
base_url="https://inference.pearlresearch.ai/v1",
api_key=os.environ.get("PEARL_API_KEY"),
)Map your model names
Model IDs are namespaced (vendor/model), and capability isn't one-to-one across families, treat this as the starting map, then spot-check on your own prompts in the playground:
| If you use | Start with | Why |
|---|---|---|
| Frontier reasoning / agent models (o-series, GPT-5-class) | deepseek-ai/DeepSeek-V4-Pro | Reasoning with a 1M-token context |
| Mini / nano tiers | deepseek/deepseek-v4-flash-0731 | Fast, cheap, still reasons and calls tools |
| General chat (GPT-4o-class) | zai-org/GLM-5.2 | Strong general chat with a 1M context; returns its thinking in reasoning |
| Fast multimodal tiers (GPT-4o-mini-class) | zai-org/GLM-5.3-Flash | Compact and fast with image input, tools, and visible reasoning |
| Structured extraction workloads | deepseek/deepseek-v4-flash-0731 | Cheap, fast JSON-mode extraction |
| Vision (image understanding) | google/gemma-4-31b-it | Text + image input at a small-model price |
Adjust for the differences
- Structured outputs:
json_objectis supported;json_schemais not, describe keys in the prompt and validate client-side (see Structured outputs). - Images:
image_urlaccepts base64 data URIs only, the engine never fetches remote URLs (see Vision). - Reasoning: unlike the o-series, the chain of thought is returned to you, in
reasoning, billed as output tokens (see Reasoning). - Endpoints: chat completions, completions, and models only, embeddings, image generation, audio, batches, and assistants aren't served, so keep those workloads where they are.
- Extra knobs:
top_k,min_p, and thereasoningobject exist here and don't exist on OpenAI, viaextra_body; conversely OpenAI'sreasoning_effortis rejected with400here, send{"reasoning": {"effort": …}}instead. Parameters outside the documented surface aren't guaranteed. - Billing: prepaid credits instead of monthly invoicing, an empty balance returns
402, so turn on auto-recharge before pointing production traffic here.
Verify, then watch the numbers
Run your own evaluation prompts side by side in the playground before cutting over, then watch the first days of traffic in Analytics, cost per model tells you quickly whether the mapping you chose is the right one.
Migrating an agent or tool rather than code? The coding agent setup guide covers opencode, Aider, and IDE assistants.