# 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.

Source: https://oneaiapikey.com/docs/migrate

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

1. Create a key under [API keys](https://oneaiapikey.com/console/keys).
2. Point your SDK or tool at the base URL for the format it uses.
3. Replace model ids with ids from the [models table](https://oneaiapikey.com/docs/models#current-models).
4. 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:

```bash
# 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

Python:

```python
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"}],
)
```

Node:

```js
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_format` on GPT models, images in messages, `reasoning_effort`, and the [Responses API](https://oneaiapikey.com/docs/responses) 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 `404` or `501`.
- **Other models, same code:** you can now send the same request to Claude, Grok, DeepSeek and other families. Read [Claude models in this format](https://oneaiapikey.com/docs/chat-completions#claude-models-in-this-format) before you switch a request that uses `response_format`.

## From the Anthropic API

Python:

```python
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"}],
)
```

Node:

```js
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_control` prompt caching, extended `thinking`, and `anthropic-beta` headers, which are passed through.
- **Base URL:** no `/v1` at the end. The SDKs and Claude Code add `/v1/messages` themselves.
- **Not available:** token counting (`/v1/messages/count_tokens`), Message Batches and the Files API. Estimate tokens on your side, or read `usage` from the reply.
- **Claude Code and agents:** see the [Claude Code guide](https://oneaiapikey.com/docs/guides/claude-code) 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](https://oneaiapikey.com/docs/models#current-models); 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 `reasoning` object (`{"effort": "high"}`). Extra attribution headers such as `HTTP-Referer` or `X-Title` are not needed and can stay.
- **Routing options** such as provider preferences or a `models` fallback 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](https://oneaiapikey.com/docs/rate-limits#when-one-model-keeps-failing)).
- **Billing** is a prepaid balance in US dollars. Each request is billed at the rates on the [models page](https://oneaiapikey.com/docs/models#current-models); there is no per-request platform fee on top.

## Features that differ by model

> **Check these before you switch models:** - `response_format` (JSON mode and JSON Schema) is dropped when a Claude model is called through chat completions. Use a forced tool call or `/v1/messages` instead. See [Structured output](https://oneaiapikey.com/docs/structured-output#claude-models).
> - Prompt caching on Claude works only through `/v1/messages`. See [Prompt caching](https://oneaiapikey.com/docs/prompt-caching).
> - Claude needs `max_tokens`; through chat completions it defaults to 8192 when you leave it out.

## Check that it worked

Send one cheap request, then open the [usage page](https://oneaiapikey.com/console/usage). The request should be listed with its model, key, tokens and cost. If it fails, the [Errors](https://oneaiapikey.com/docs/errors) page explains each status code.

## Related

- [Quickstart](https://oneaiapikey.com/docs/quickstart): your first request from scratch.
- [SDKs and frameworks](https://oneaiapikey.com/docs/sdks): base URL settings for each library.
