Migrate from OpenAI, Anthropic or another API
OceanToken speaks the OpenAI API, and every chat model also speaks the Anthropic Messages API. Moving an app is two settings, the base URL and the key, plus the model names.
From the OpenAI SDK
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.oceantoken.ai/v1", # was https://api.openai.com/v1
api_key=os.environ["OCEANTOKEN_API_KEY"], # an OceanToken key, sk-...
)
In TypeScript the options are baseURL and apiKey. Then add the publisher in front of each model name: gpt-5-mini becomes openai/gpt-5-mini. The Models page lists every ID.
No code change at all: the OpenAI SDKs for Python and Node.js read two environment variables, so an app that creates its client without arguments moves with
export OPENAI_BASE_URL=https://api.oceantoken.ai/v1
export OPENAI_API_KEY=$OCEANTOKEN_API_KEY
and the new model names. Many tools built on the OpenAI SDK read the same variables.
From the Anthropic SDK
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://api.oceantoken.ai", # no /v1: the SDK adds it
api_key=os.environ["OCEANTOKEN_API_KEY"],
)
Or set ANTHROPIC_BASE_URL=https://api.oceantoken.ai and ANTHROPIC_API_KEY to your OceanToken key. Claude models are named anthropic/claude-sonnet-4.6, anthropic/claude-haiku-4.5 and so on, and the same code calls any other chat model on OceanToken by its ID.
From another multi-model API
If you use another service that offers many models behind one OpenAI-compatible API:
- Base URL and key:
https://api.oceantoken.ai/v1and your OceanToken key. - Model IDs have the same
publisher/modelform, so most carry over unchanged. Check each againstGET /v1/modelsor the Models page; a name that does not exist is refused with400 model_not_found, never swapped for another model. - Backup models: put them in
fallbacks, a list of model IDs tried in order if your model fails (Retries and failover). Other ways of listing backup models are not supported. - Routing preferences that pick a hosting provider, and attribution headers, are not needed and not supported. Each model is served from official or authorized sources, failover between them is automatic, and the price does not depend on which one answers (Retries and failover).
:freemodels exist here too.- Video uses
POST /v1/videosand a job you poll (Video).
What works the same
- Request and response bodies of each shape, including streaming, tool calling, image input and structured output.
- The error envelope,
{"error": {"message", "type", "param", "code"}}. - Every OpenAI-compatible SDK and framework: set the base URL and key. Guides: Vercel AI SDK, coding agents.
What is different
| Topic | On OceanToken |
|---|---|
| Parameters a model does not support | Dropped, and the request runs. A success does not prove a parameter took effect (Which API shape). |
| Errors | A few statuses differ: an empty balance is 400 insufficient_credits, not a 429; an unknown model is 400. Branch on code (Migrating from OpenAI). |
| Not offered | Batches, fine-tuning, and listing or reading uploaded files answer 501 not_supported (Errors). Send each request to its regular endpoint. |
| Billing | Prepaid: requests run while your balance is above $0. Each key can have its own credit limit (Create an API key). |
| What a request cost | The x-oceantoken-cost header, GET /v1/usage/{request_id} for streams, and Logs in the console (What a request cost). |
| Generated media | Images and video come back as links valid for 24 hours; download what you keep (Limits → Retention). |
| Request ID | Log the x-oceantoken-request-id header and quote it when you write to us (Errors). |
Checklist
- Create a key for the app, with a credit limit, and add credits.
- Change the base URL and key, or set the environment variables above.
- Rename the models; check each with
GET /v1/models. - If you branch on error statuses, read Errors; retry only what is retryable.
- Run your tests, including one with each parameter you depend on, and check the requests under Logs in the console.