OpenAI SDK
base_url 하나만 바꾸면 된다
MyIP OpenRouter 의 /api/v1 은 OpenAI Chat Completions 규격과 호환됩니다. 이미 OpenAI 공식 SDK 로 짜 둔 코드가 있다면 base URL 과 API 키만 바꾸면 그대로 동작합니다.
| 항목 | 값 |
|---|---|
| Base URL | https://openrouter.myip.co.kr/api/v1 |
| 인증 | Authorization: Bearer sk-mo-v1-… (SDK 가 api_key 로 붙입니다) |
| 환경 변수 | MYIP_API_KEY |
| 예제 모델 | google/gemma-4-26b-a4b, lgai/exaone-4.0-32b |
키는 /settings/keys 에서 발급합니다. 추론용 키는 sk-mo-v1- 로 시작합니다.
Python
pip install openai
export MYIP_API_KEY="sk-mo-v1-..."import os
from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.myip.co.kr/api/v1",
api_key=os.environ["MYIP_API_KEY"],
default_headers={
# 선택 사항. 대시보드에서 앱별로 사용량을 구분할 때 씁니다.
"HTTP-Referer": "https://example.com",
"X-Title": "My Example App",
},
)
completion = client.chat.completions.create(
model="google/gemma-4-26b-a4b",
messages=[
{"role": "system", "content": "당신은 간결하게 답하는 도우미입니다."},
{"role": "user", "content": "한국의 수도는?"},
],
temperature=0.7,
max_tokens=256,
)
print(completion.choices[0].message.content)
print(completion.usage)TypeScript / JavaScript
npm install openai
export MYIP_API_KEY="sk-mo-v1-..."import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://openrouter.myip.co.kr/api/v1',
apiKey: process.env.MYIP_API_KEY,
defaultHeaders: {
'HTTP-Referer': 'https://example.com',
'X-Title': 'My Example App',
},
});
const completion = await client.chat.completions.create({
model: 'google/gemma-4-26b-a4b',
messages: [
{ role: 'system', content: '당신은 간결하게 답하는 도우미입니다.' },
{ role: 'user', content: '한국의 수도는?' },
],
temperature: 0.7,
max_tokens: 256,
});
console.log(completion.choices[0]?.message.content);
console.log(completion.usage);스트리밍
stream=True 만 켜면 됩니다. stream_options.include_usage 는 우리가 항상 붙여서 업스트림에 보내므로 직접 지정할 필요가 없습니다.
stream = client.chat.completions.create(
model="lgai/exaone-4.0-32b",
messages=[{"role": "user", "content": "짧은 시를 하나 써 줘"}],
stream=True,
)
cost_krw = None
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage is not None:
# 마지막 usage 청크에 이 요청의 청구액(원)이 실려 옵니다.
cost_krw = getattr(chunk.usage, "cost", None) or chunk.usage.model_extra.get("cost")
print(f"\n비용: {cost_krw} 원")const stream = await client.chat.completions.create({
model: 'lgai/exaone-4.0-32b',
messages: [{ role: 'user', content: '짧은 시를 하나 써 줘' }],
stream: true,
});
let costKrw: number | undefined;
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
const usage = chunk.usage as { cost?: number } | undefined;
if (usage?.cost !== undefined) costKrw = usage.cost;
}
console.log(`\n비용: ${costKrw} 원`);비용 헤더 읽기
비스트리밍 응답에는 비용과 정산 후 잔액이 헤더로 옵니다. 금액 단위는 원(KRW) 입니다.
| 헤더 | 뜻 |
|---|---|
X-MyIP-Cost-KRW | 이 요청의 청구액 (비스트리밍만) |
X-MyIP-Credit-Balance | 정산 후 잔액 (비스트리밍만) |
X-MyIP-Currency | 항상 KRW |
X-MyIP-Model | 실제로 응답한 모델 id |
X-MyIP-Provider | 응답한 provider 표시명 |
X-MyIP-Generation-Id | GET /api/v1/generation 조회용 id |
raw = client.chat.completions.with_raw_response.create(
model="google/gemma-4-26b-a4b",
messages=[{"role": "user", "content": "안녕"}],
)
print(raw.headers["x-myip-cost-krw"], raw.headers["x-myip-currency"])
print(raw.headers["x-myip-generation-id"])
completion = raw.parse()
print(completion.choices[0].message.content)const { data, response } = await client.chat.completions
.create({
model: 'google/gemma-4-26b-a4b',
messages: [{ role: 'user', content: '안녕' }],
})
.withResponse();
console.log(response.headers.get('x-myip-cost-krw'));
console.log(response.headers.get('x-myip-generation-id'));
console.log(data.choices[0]?.message.content);스트리밍에서는 헤더가 첫 바이트보다 먼저 나가므로 비용을 실을 수 없습니다. 위 usage 청크를 쓰거나, 끝난 뒤 GET /api/v1/generation?id=… 으로 조회하세요.
폴백 모델
우리 고유 확장으로 models 배열을 보내면 앞에서부터 시도합니다. OpenAI SDK 는 모르는 필드이므로 extra_body(Python) 로 넣습니다.
completion = client.chat.completions.create(
model="lgai/exaone-4.0-32b",
messages=[{"role": "user", "content": "안녕"}],
extra_body={"models": ["lgai/exaone-4.0-32b", "google/gemma-4-26b-a4b"]},
)자세한 내용은 모델 폴백 을 보세요.
동작하지 않는 것
OpenAI SDK 의 모든 기능이 우리 쪽에 있는 것은 아닙니다. 다음은 404 not_supported 를 돌려줍니다.
client.embeddings.*client.images.*,client.audio.*client.responses.*(Responses API)client.batches.*,client.files.*
전체 목록과 응답 형식은 지원하지 않는 엔드포인트 에 있습니다.
client.chat.completions.* 와 client.completions.*, 그리고 client.models.list() 는 정상 동작합니다.
관련 문서
- 인증 — 키 발급과 헤더
- 요청 파라미터 — 지원하는 파라미터 전체
- 툴 콜링
- 프레임워크 연동 개요
마지막 수정 2026. 9. 5.