Przejście z OpenRoutera to jedna linijka

Zmień swój base URL i wstaw klucz OrcaRouter. Modele, SDK i cała reszta kodu zostają dokładnie takie, jakie są — zmienia się tylko identyfikatory routerów openrouter/.

Trzy rzeczy do sprawdzenia

  1. Użyj właściwego base URL dla swojego SDK — SDK OpenAI oczekuje https://api.orcarouter.ai/v1. Pozostałe dwa oczekują https://api.orcarouter.ai — ścieżkę każde dopisuje samo.
  2. Zamień klucz API na klucz OrcaRouter — Wartość się zmienia — klucz OpenRouter nie uwierzytelni się tutaj — ale miejsce nie: czytamy ten nagłówek, który Twój SDK już wysyła.
  3. Zachowaj nazwy modeli — Używamy tych samych nazw vendor/model, więc anthropic/claude-sonnet-4 działa bez zmian. Wyjątkiem są własne identyfikatory routerów openrouter/ w OpenRouterze: te się zmienia.

Przed i po: linia, która się zmienia

OrcaRouter natywnie obsługuje API OpenAI, Anthropic i Gemini, więc zostajesz przy SDK, którego już używasz. W każdym fragmencie linie zaczynające się od - należy usunąć, a linie zaczynające się od + — dodać.

OpenAI — Python

  client = OpenAI(
-     base_url="https://openrouter.ai/api/v1",
+     base_url="https://api.orcarouter.ai/v1",
      api_key=ORCAROUTER_API_KEY,
  )

To jedyna zmiana w kodzie. Wstaw jeszcze klucz OrcaRouter — nazwy modeli, wiadomości i streaming zostają bez zmian, chyba że wywołujesz identyfikator routera openrouter/.

Anthropic — Python

  client = Anthropic(
+     base_url="https://api.orcarouter.ai",
      api_key=ORCAROUTER_API_KEY,
  )

Obsługujemy API Anthropic natywnie, czego OpenRouter nie robi. Jeśli wywoływałeś Claude przez SDK OpenAI, żeby dopasować się do OpenRoutera, możesz z tego zrezygnować.

Gemini — TypeScript

  const ai = new GoogleGenAI({
    apiKey: ORCAROUTER_API_KEY,
+   httpOptions: { baseUrl: "https://api.orcarouter.ai" },
  });

API Gemini również obsługujemy natywnie, więc SDK Google działa bez zmian.

Pełne przykłady dla każdego SDK

Importy, klient i jedno prawdziwe wywołanie. Działa bez zmian, gdy tylko ORCAROUTER_API_KEY jest ustawiona w Twoim środowisku.

OpenAI — Python

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.orcarouter.ai/v1",
    api_key=os.environ["ORCAROUTER_API_KEY"],
)

response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4",
    messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)

OpenAI — TypeScript

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.orcarouter.ai/v1",
  apiKey: process.env.ORCAROUTER_API_KEY,
});

const response = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-4",
  messages: [{ role: "user", content: "Hello" }],
});
console.log(response.choices[0].message.content);

OpenAI — cURL

curl https://api.orcarouter.ai/v1/chat/completions \
  -H "Authorization: Bearer $ORCAROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Anthropic — Python

import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.orcarouter.ai",
    api_key=os.environ["ORCAROUTER_API_KEY"],
)

message = client.messages.create(
    model="anthropic/claude-sonnet-4",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
)
print(message.content[0].text)

Anthropic — TypeScript

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  baseURL: "https://api.orcarouter.ai",
  apiKey: process.env.ORCAROUTER_API_KEY,
});

const message = await client.messages.create({
  model: "anthropic/claude-sonnet-4",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello" }],
});
console.log(message.content[0].text);

Anthropic — cURL

curl https://api.orcarouter.ai/v1/messages \
  -H "x-api-key: $ORCAROUTER_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Gemini — Python

import os
from google import genai

client = genai.Client(
    api_key=os.environ["ORCAROUTER_API_KEY"],
    http_options={"base_url": "https://api.orcarouter.ai"},
)

response = client.models.generate_content(
    model="google/gemini-2.5-pro",
    contents="Hello",
)
print(response.text)

Gemini — TypeScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
  apiKey: process.env.ORCAROUTER_API_KEY,
  httpOptions: { baseUrl: "https://api.orcarouter.ai" },
});

const response = await ai.models.generateContent({
  model: "google/gemini-2.5-pro",
  contents: "Hello",
});
console.log(response.text);

Gemini — cURL

curl "https://api.orcarouter.ai/v1beta/models/google/gemini-2.5-pro:generateContent" \
  -H "x-goog-api-key: $ORCAROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{"parts": [{"text": "Hello"}]}]
  }'

Identyfikatory modeli: co zmienić

Używamy tych samych nazw vendor/model, więc anthropic/claude-sonnet-4 działa bez zmian. Wyjątkiem są własne identyfikatory routerów openrouter/ w OpenRouterze: te się zmienia.

W OpenRouterW OrcaRouter
openrouter/autoorcarouter/auto
openrouter/freeorcarouter/free
Każdy inny router openrouter/Brak odpowiednika — wskaż konkretny model
Każdy identyfikator vendor/model, np. anthropic/claude-sonnet-4Ten sam identyfikator, bez zmian

Różnice w rozliczeniach

Cztery rzeczy, których nie robimy

Lepiej wiedzieć teraz niż odkryć to na produkcji.

Najczęstsze pytania

Czy OrcaRouter może bezpośrednio zastąpić OpenRouter?

W większości integracji tak. Zmień base URL i podstaw klucz OrcaRouter; SDK, nazwy modeli, wiadomości i streaming pozostają bez zmian. Wyjątki to własne identyfikatory routerów openrouter/ z OpenRouter, którym zmienia się nazwy, oraz cztery rzeczy, których OrcaRouter celowo nie robi, wymienione wyżej.

Jakiego base URL potrzebuje każde SDK?

SDK OpenAI oczekuje https://api.orcarouter.ai/v1. Pozostałe dwa oczekują https://api.orcarouter.ai — ścieżkę każde dopisuje samo.

Czy mogę dalej używać klucza API z OpenRouter?

Wartość się zmienia — klucz OpenRouter nie uwierzytelni się tutaj — ale miejsce nie: czytamy ten nagłówek, który Twój SDK już wysyła.

Czym zastąpić openrouter/auto i openrouter/free?

Routery OrcaRoutera to te z orcarouter/. Dwa odpowiadają ich routerom wprost: użyj orcarouter/auto zamiast openrouter/auto i orcarouter/free zamiast openrouter/free — w obu przypadkach ta sama idea, dobieramy model za Ciebie w momencie zapytania, a drugi zostawia Cię na poziomie bezkosztowym. Pozostałe ich routery nie mają tu odpowiednika, więc wskaż konkretny model.

Czy routing zapasowy działa tak samo?

Przenieś models i route do wnętrza extra_body. Poza tym wszystko działa tak samo: wypisz modele w kolejności preferencji, a my spróbujemy ich po kolei. Minimum 2 modele, maksimum 5. Warto zrobić to porządnie. Na najwyższym poziomie ich nie czytamy, więc Twoje trasy zapasowe po cichu przestają działać, a we wdrożeniach, które przekazują treść zapytania bez zmian, model otrzyma te dodatkowe pola i może odrzucić całe wywołanie.

Jak sprawdzić, ile kosztowało zapytanie?

Odczytaj X-Orca-Request-Id z odpowiedzi, a potem wywołaj /v1/generation. 501 znaczy, że na tym wdrożeniu odpytywanie o koszt jest wyłączone.

Czy X-Title i HTTP-Referer nadal identyfikują moją aplikację?

Wyślij X-Title, a Twoja aplikacja zachowa swoją nazwę w statystykach bez żadnych zmian; czytamy też nazwy nagłówków samego OpenRoutera. Sam HTTP-Referer wskaże nazwę Twojej aplikacji tylko wtedy, gdy jej domena jest jedną z już rozpoznawanych, więc dla pewności wyślij nagłówek tytułu. Ten punkt jest tu po to, żebyś ich przez pomyłkę nie usunął.

Co się dzieje z provider i transforms w moich zapytaniach?

Nie używamy żadnego z nich. Na zwykłym kanale są odrzucane, zanim żądanie dotrze do modelu; na kanale ustawionym na przekazywanie surowego ciała są przesyłane dalej, a restrykcyjny dostawca może żądanie odrzucić. Usunięcie ich jest bezpieczne w obu przypadkach.

Jakie endpointy udostępnia OrcaRouter?

Wszystko, czego oczekujesz, plus kilka, których OpenRouter nie ma. Dostępne tutaj, a niedostępne w OpenRouter: /v1/messages, /v1beta/models … generateContent, /v1/rerank i /v1/realtime. Niedostępne: /v1/fine-tunes, GET /v1/files i /v1/images/variations.

Czy błędy wracają w tym samym formacie?

Błędy wracają w tym samym kształcie, który już obsługujesz. Kieruj się statusem HTTP: ponów 429, gdy wysyłamy Retry-After, odczekaj i ponów 5xx poza 501 — który oznacza, że tego wywołania w ogóle nie obsługujemy — a 4xx na wywołaniu relayu potraktuj jako coś do poprawienia w Twoim żądaniu. Wyjątkiem jest 404 z /v1/generation: może po prostu znaczyć, że żądanie jeszcze się nie rozliczyło, więc ponów je przez chwilę. Nie czytaj error.type jako źródła: orcarouter_api_error jest zawsze nasz, ale przy części własnych awarii celowo wysyłamy słownictwo dostawcy, żeby Twój SDK poszedł swoją zwykłą gałęzią — limit tempa nałożony przez nas i ten nałożony przez model mówią tak samo rate_limit_error. Podaj X-Orca-Request-Id, gdy potrzebujesz, żebyśmy odszukali pojedyncze wywołanie.