Switch from another API
Move from the OpenAI SDK, the Anthropic SDK, OpenRouter, or a queue-style media API such as fal or Replicate.
Most moves are a new base URL, a new key and new model ids. Model ids here are our own: take them from Models or GET /v1/models, never from another provider's list.
From the OpenAI SDK
Change two lines. Everything else (messages, tools, streaming, the Responses API) stays.
from openai import OpenAI
client = OpenAI(
base_url="https://pinerouter.ai/v1", # was https://api.openai.com/v1
api_key="sk-...", # a key from this site
)
r = client.chat.completions.create(model="gpt-5-5", messages=[{"role": "user", "content": "Hi"}])import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.example.com/v1", // was https://api.openai.com/v1
apiKey: "sk-...", // a key from this site
});Or set the environment variables the SDK already reads: OPENAI_BASE_URL=https://pinerouter.ai/v1 and OPENAI_API_KEY=sk-....
| You used | Use here |
|---|---|
| OpenAI's model ids | Our ids, such as gpt-5-5, gpt-6-luna or gpt-6-1-sol, from Models |
/v1/chat/completions, /v1/responses | The same paths |
/v1/images/generations, /v1/videos | The same paths, for image and video models; see Images and Video |
| Files, Assistants, Batch, fine-tuning | Not available. Only the endpoints in the API reference are served |
From the Anthropic SDK
Point the SDK at our address without /v1. It calls POST /v1/messages, which any text model here can answer.
import anthropic
client = anthropic.Anthropic(base_url="https://pinerouter.ai", api_key="sk-...")
msg = client.messages.create(
model="gpt-5-2",
max_tokens=500,
messages=[{"role": "user", "content": "Hi"}],
)
print(msg.content[0].text)import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({ baseURL: "https://pinerouter.ai", apiKey: "sk-..." });
const msg = await client.messages.create({
model: "gpt-5-2",
max_tokens: 500,
messages: [{ role: "user", content: "Hi" }],
});Environment variables work too: ANTHROPIC_BASE_URL=https://pinerouter.ai and ANTHROPIC_API_KEY=sk-... (Claude Code reads ANTHROPIC_AUTH_TOKEN; see Claude Code).
- Claude models are not on the Models list today. Pick another text model, such as
gpt-5-2,gemini-3-8-flashorkimi-k3. - Tools, system prompts and streaming are passed to the model in Messages format. Whether a feature such as extended thinking works depends on the model you pick.
- The Message Batches, Files and token counting endpoints are not available.
From OpenRouter
| OpenRouter | Here |
|---|---|
https://openrouter.ai/api/v1 | https://pinerouter.ai/v1 |
maker/model ids | Our ids, such as gpt-5-5 or gemini-3-8-flash, from Models. Text model ids have no maker prefix |
models: [...] fallback list, provider routing options | Not available. Each request goes to the one model you name; handle fallbacks in your code |
| Bring your own provider key | Not available. Every request is billed from your balance here |
| Credits | Prepaid balance in Wallet |
The OpenAI and Anthropic SDK setups above apply unchanged. Streaming works the same way, and usage comes in the last chunk; see Streaming.
From fal, Replicate and other queue-style media APIs
The flow is the same idea: submit, then poll for the result.
| Queue-style API | Here |
|---|---|
| Submit to the model's queue | POST /v1/jobs with {"model": "<id>", "input": {...}} |
| Status and result | GET /v1/jobs/{id}: data.status is queued, running, succeeded or failed |
| Output files | data.outputs, a list of links |
| Model inputs | The model's own fields, listed with options and defaults on its page under Models |
curl https://pinerouter.ai/v1/jobs \
-H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
-d '{"model": "nano-banana-pro", "input": {"prompt": "A ceramic mug on a beige backdrop"}}'What is different:
- Webhooks or polling. Pass
webhook_urlto be called when the job finishes (Standard Webhooks signatures), or poll every 5 to 10 seconds; see Jobs. A copy-paste helper is on SDKs. - Files go in as
https://links. Pass any public link, or upload withPOST /v1/filesand use the returnedurl(kept 1 day), in the model's field such asimage_urlorimage_urls. - Results last 7 days. Download what you want to keep. See Data and logging.
- No cancel. A started job runs to the end. A failed job costs nothing.
- Cost is known up front. Each model's page lists its price per setting. A job reserves its expected cost plus 20% and settles at the real cost.
- Field names differ by model. Do not copy inputs from another provider's schema; read the model's page.
You can also use OpenAI-style POST /v1/images/generations and POST /v1/videos for image and video models if your code already speaks that format.
