Optimize
Migrating
Move existing code from the OpenAI API, the Anthropic API, OpenRouter or another gateway. Change the base URL, key and model ids, then check the few features that differ.
Updated View .md
On this page
Most code moves over with three changes: the base URL, the API key, and the model id. Request and response shapes stay the same, because Relaykit speaks the OpenAI and Anthropic formats directly. This page lists those changes and the features that behave differently.
The short version
- Create a key under API keys.
- Point your SDK or tool at the base URL for the format it uses.
- Replace model ids with ids from the models table.
- Run your tests, then read the section below for where you came from.
If your code reads the standard environment variables, you may not need to touch it at all:
.env
# OpenAI SDKs (Python, Node, and most tools built on them)
OPENAI_BASE_URL=https://api.oneaiapikey.com/v1
OPENAI_API_KEY=<your Relaykit key>
# Anthropic SDKs (no /v1 at the end)
ANTHROPIC_BASE_URL=https://api.oneaiapikey.com
ANTHROPIC_API_KEY=<your Relaykit key>From the OpenAI API
import os
from openai import OpenAI
# Before: client = OpenAI()
client = OpenAI(
base_url="https://api.oneaiapikey.com/v1",
api_key=os.environ["RELAYKIT_API_KEY"],
)
reply = client.chat.completions.create(
model="gpt-5.6-terra", # an id from the models table
messages=[{"role": "user", "content": "Hello"}],
)import OpenAI from "openai";
// Before: const client = new OpenAI();
const client = new OpenAI({
baseURL: "https://api.oneaiapikey.com/v1",
apiKey: process.env.RELAYKIT_API_KEY,
});
const reply = await client.chat.completions.create({
model: "gpt-5.6-terra", // an id from the models table
messages: [{ role: "user", content: "Hello" }],
});- Works the same: chat completions, streaming with
stream_options, tools and parallel tool calls,response_formaton GPT models, images in messages,reasoning_effort, and the Responses API on GPT models. - Stateless only: the Responses API does not store responses for you to fetch later. Send the full history each time instead of relying on stored state.
- Not available: Assistants, Threads, Files, Batch, fine-tuning and image variations. Requests to them fail with
404or501. - Other models, same code: you can now send the same request to Claude, Grok, DeepSeek and other families. Read Claude models in this format before you switch a request that uses
response_format.
From the Anthropic API
import anthropic, os
# Before: client = anthropic.Anthropic()
client = anthropic.Anthropic(
base_url="https://api.oneaiapikey.com", # no /v1: the SDK adds /v1/messages
api_key=os.environ["RELAYKIT_API_KEY"],
)
message = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello"}],
)import Anthropic from "@anthropic-ai/sdk";
// Before: const client = new Anthropic();
const client = new Anthropic({
baseURL: "https://api.oneaiapikey.com", // no /v1: the SDK adds /v1/messages
apiKey: process.env.RELAYKIT_API_KEY,
});
const message = await client.messages.create({
model: "claude-sonnet-5-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello" }],
});- Works the same: Messages with streaming, system prompts, tools, images and PDFs,
cache_controlprompt caching, extendedthinking, andanthropic-betaheaders, which are passed through. - Base URL: no
/v1at the end. The SDKs and Claude Code add/v1/messagesthemselves. - Not available: token counting (
/v1/messages/count_tokens), Message Batches and the Files API. Estimate tokens on your side, or readusagefrom the reply. - Claude Code and agents: see the Claude Code guide for the two environment variables it needs.
From OpenRouter or another gateway
- Model ids have no provider prefix here. Look up each model in the models table; spellings and version numbers can differ from other gateways, so copy the id rather than editing the old one.
- The OpenAI-style request is the same, including the
reasoningobject ({"effort": "high"}). Extra attribution headers such asHTTP-RefererorX-Titleare not needed and can stay. - Routing options such as provider preferences or a
modelsfallback list are not used here. Each model id goes to one route. If you relied on automatic fallback, put the fallback in your own code (see Rate limits and retries). - Billing is a prepaid balance in US dollars. Each request is billed at the rates on the models page; there is no per-request platform fee on top.
Features that differ by model
Check that it worked
Send one cheap request, then open the usage page. The request should be listed with its model, key, tokens and cost. If it fails, the Errors page explains each status code.
Related
- Quickstart: your first request from scratch.
- SDKs and frameworks: base URL settings for each library.