PineRouterDocs
GuidesModelsAPI referenceApps

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 usedUse here
OpenAI's model idsOur ids, such as gpt-5-5, gpt-6-luna or gpt-6-1-sol, from Models
/v1/chat/completions, /v1/responsesThe same paths
/v1/images/generations, /v1/videosThe same paths, for image and video models; see Images and Video
Files, Assistants, Batch, fine-tuningNot 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-flash or kimi-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

OpenRouterHere
https://openrouter.ai/api/v1https://pinerouter.ai/v1
maker/model idsOur 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 optionsNot available. Each request goes to the one model you name; handle fallbacks in your code
Bring your own provider keyNot available. Every request is billed from your balance here
CreditsPrepaid 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 APIHere
Submit to the model's queuePOST /v1/jobs with {"model": "<id>", "input": {...}}
Status and resultGET /v1/jobs/{id}: data.status is queued, running, succeeded or failed
Output filesdata.outputs, a list of links
Model inputsThe 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_url to 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 with POST /v1/files and use the returned url (kept 1 day), in the model's field such as image_url or image_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.