OpenRouter: 키 하나로 모든 LLM을 부르는 통합 API

LLM 호출 한 줄을 코드에 붙이는 건 쉽습니다. 그런데 제공사가 둘, 셋으로 늘어나는 순간 이야기가 달라지죠. OpenAI SDK 깔고, Anthropic SDK 또 깔고, 키를 각각 발급받아 환경변수로 빼고, 비용은 대시보드 세 군데를 들여다봐야 하고요. 게다가 새 모델이 나올 때마다 “이거 한번 써볼까?” 하면 또 가입하고 결제 정보를 등록하는 일이 반복됩니다. 정작 하고 싶은 건 “프롬프트 보내고 답 받기” 한 줄인데 말이죠. 🤔
OpenRouter는 이 번거로움을 키 하나로 정리합니다. OpenAI, Anthropic, Google, Meta, Mistral 등 수백 개 모델을 단일 API와 단일 크레딧으로 부를 수 있게 해주는 서비스인데요. 이번 글에서는 OpenRouter가 정확히 무엇인지부터 첫 호출, 모델 이름 규칙, 프로바이더 라우팅, 폴백, 그리고 비용 계량까지 차근차근 살펴보겠습니다.
OpenRouter란? 모델을 대신 사다 주는 리셀러
가장 먼저 OpenRouter의 정체를 짚고 넘어가야 합니다. Cloudflare AI Gateway 글에서 프록시와 리셀러를 구분했는데, OpenRouter는 그중 리셀러(reseller) 쪽입니다.
게이트웨이가 우리 요청이 제공사로 나가는 길목에 서는 프록시라면, OpenRouter는 한 발 더 들어와서 제공사와의 관계를 통째로 대신 떠안아요. 우리는 OpenAI나 Anthropic에 따로 가입할 필요 없이, OpenRouter 키 하나로 그들의 모델을 부른 뒤 OpenRouter의 크레딧으로 정산받습니다. 제공사 키를 우리가 들고 있지 않다는 게 핵심이에요. Void AI가 Cloudflare 자격증명으로 외부 모델을 대신 호출해준 것과 같은 구조인데, OpenRouter는 그 범위를 수백 개 모델로 넓혀둔 셈입니다.
여기에 결정적인 편의가 하나 더 있습니다. OpenRouter는 OpenAI 호환 API라는 점이에요. 즉 OpenAI를 부르던 기존 코드에서 주소(baseURL)와 키만 바꾸면 곧바로 Claude든 Gemini든 라마든 같은 코드로 부를 수 있습니다. 제공사마다 SDK를 따로 깔거나 응답 파싱을 분기할 필요가 사라지는 거죠.
첫 호출: baseURL 한 줄 바꾸기
먼저 openrouter.ai에 가입하고 키를 발급받습니다. 그다음 OpenAI SDK를 그대로 설치하고요.
$ bun add openai
$ npm install openai
평소 OpenAI를 부르던 코드에서 baseURL을 OpenRouter 주소로, apiKey를 OpenRouter 키로 갈아끼웁니다.
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENROUTER_API_KEY, // sk-or-v1-... 형식의 OpenRouter 키
baseURL: "https://openrouter.ai/api/v1",
});
const completion = await client.chat.completions.create({
model: "anthropic/claude-sonnet-4",
messages: [{ role: "user", content: "안녕하세요!" }],
});
console.log(completion.choices[0].message.content);
달라진 건 딱 두 줄입니다. 주소를 https://openrouter.ai/api/v1로 바꾸고, 키를 OpenRouter 키로 넣은 것뿐이에요. model에 OpenAI가 아닌 anthropic/claude-sonnet-4를 넣었는데도 같은 chat.completions.create()로 호출된다는 점을 눈여겨보세요. 이게 OpenAI 호환 API의 힘입니다.
선택적으로 두 헤더를 더 실으면 좋은데요. HTTP-Referer에 우리 서비스 주소를, X-Title에 앱 이름을 넣으면 openrouter.ai의 모델 사용 순위에 우리 앱이 노출됩니다. 없어도 호출은 잘 되니 필수는 아니에요.
const client = new OpenAI({
apiKey: process.env.OPENROUTER_API_KEY,
baseURL: "https://openrouter.ai/api/v1",
defaultHeaders: {
"HTTP-Referer": "https://myapp.com",
"X-Title": "My App",
},
});
모델 이름은 provider/model
OpenRouter에서 모델 이름은 항상 제공사/모델 형태입니다. openai/gpt-4o, anthropic/claude-sonnet-4, google/gemini-2.5-flash, meta-llama/llama-3.3-70b-instruct처럼요. 앞쪽이 제공사, 뒤쪽이 모델 이름이죠.
덕분에 모델을 바꾸는 일이 문자열 하나 교체하는 작업이 됩니다. “일단 저렴한 모델로 만들어보고 나중에 더 똑똑한 모델로 갈아끼우는” 실험이 정말 쉬워져요.
// 가벼운 작업은 빠르고 저렴한 모델로
await client.chat.completions.create({
model: "google/gemini-2.5-flash",
messages: [{ role: "user", content: prompt }],
});
// 복잡한 추론은 큰 모델로 — model만 변경
await client.chat.completions.create({
model: "anthropic/claude-sonnet-4",
messages: [{ role: "user", content: prompt }],
});
쓸 수 있는 모델이 뭐가 있는지는 openrouter.ai/models에서 둘러보거나, /api/v1/models 엔드포인트로 코드에서 직접 조회할 수 있습니다. 각 모델의 입력/출력 토큰 단가와 컨텍스트 길이까지 함께 내려와요.
모델 이름 뒤에는 콜론으로 변형(variant)을 붙일 수도 있습니다. 무료로 제공되는 모델은 :free가 붙는데, 속도 제한이 빡빡한 대신 비용이 들지 않아 프로토타이핑에 좋아요. 처리량을 우선하고 싶으면 :nitro, 가장 저렴한 공급자를 고르고 싶으면 :floor를 붙입니다.
await client.chat.completions.create({
model: "meta-llama/llama-3.3-70b-instruct:free", // 무료 변형
messages: [{ role: "user", content: prompt }],
});
어떤 모델을 골라야 할지 막막하다면 openrouter/auto도 있습니다. 프롬프트 내용을 보고 OpenRouter가 적절한 모델을 알아서 골라주는 자동 라우터예요.
프로바이더 라우팅: 같은 모델, 여러 공급자
여기서 OpenRouter의 진짜 묘미가 나옵니다. 같은 meta-llama/llama-3.3-70b-instruct 모델이라도, 이걸 실제로 돌려주는 공급자(provider)는 여러 곳일 수 있어요. 같은 오픈 모델을 여러 인프라 업체가 호스팅하니까요. OpenRouter는 기본적으로 이 공급자들 사이에서 트래픽을 분산하며, 한 곳이 죽으면 자동으로 다른 곳으로 넘깁니다.
이 라우팅을 요청마다 직접 제어할 수도 있는데요. 본문에 provider 객체를 넣어 우선순위나 정렬 기준을 지정합니다.
await client.chat.completions.create({
model: "meta-llama/llama-3.3-70b-instruct",
messages: [{ role: "user", content: prompt }],
// OpenAI SDK의 확장 필드로 전달
// @ts-expect-error provider는 OpenRouter 전용 옵션
provider: {
sort: "throughput", // 처리량이 가장 높은 공급자 우선
order: ["deepinfra", "together"], // 선호 공급자 순서
allow_fallbacks: true, // 위 공급자가 다 실패하면 다른 곳으로
},
});
provider에 넣을 수 있는 대표적인 옵션은 이렇습니다.
sort: 공급자를 무엇으로 정렬할지 정합니다.price는 가장 저렴한 곳,throughput은 가장 빠른 곳,latency는 응답이 가장 빨리 시작되는 곳 순으로 보냅니다.order: 선호하는 공급자를 순서대로 나열합니다. 특정 인프라를 1순위로 두고 싶을 때 써요.allow_fallbacks:order에 적은 공급자가 모두 실패했을 때 다른 공급자로 넘어갈지 정합니다.false로 두면 지정한 곳만 고집해요.require_parameters: 우리가 보낸 파라미터(예:response_format)를 지원하는 공급자만 고릅니다.data_collection: 입력 데이터를 학습에 쓸 수 있는 공급자를 거를지 정합니다.deny로 두면 데이터를 보관하지 않는 곳으로만 보내요.
이 옵션들 덕분에 “민감한 데이터라 학습에 안 쓰는 곳으로만”, “비용이 최우선이라 무조건 제일 싼 곳으로”, “속도가 생명이라 가장 빠른 곳으로” 같은 운영 정책을 요청 한 번에 걸 수 있습니다.
모델 폴백으로 끊기지 않게
프로덕션에서 가장 무서운 건 모델이 잠깐 흔들릴 때입니다. 특정 모델이 5xx를 뱉기 시작하면 우리 서비스도 같이 멈추니까요. OpenRouter는 여기에 모델 단위 폴백으로 답을 줍니다. models 배열에 모델을 우선순위대로 나열해두면, 앞 모델이 실패할 때 자동으로 다음 모델로 넘어가요.
await client.chat.completions.create({
model: "anthropic/claude-sonnet-4", // 1순위
// @ts-expect-error models는 OpenRouter 전용 옵션
models: ["openai/gpt-4o", "google/gemini-2.5-flash"], // 실패 시 차례로
messages: [{ role: "user", content: prompt }],
});
앞 절의 프로바이더 라우팅이 “같은 모델을 어느 공급자로 보낼까”를 다룬다면, 이쪽은 “이 모델이 아예 안 되면 어떤 모델로 대신할까”를 다루는 셈이에요. 비싼 상용 모델을 1순위로 두되 그게 죽으면 다른 제공사 모델로라도 서비스를 이어가는 전략이죠. 실제로 어떤 모델이 응답했는지는 응답 객체의 model 필드로 확인할 수 있습니다.
비용과 크레딧
OpenRouter는 리셀러이므로 비용 구조도 게이트웨이와 다릅니다. 먼저 크레딧을 충전해두면, 모델을 부를 때마다 각 제공사의 토큰 단가만큼 크레딧에서 빠져나가요. 토큰 단가 자체는 제공사 가격을 거의 그대로 따르고, OpenRouter는 주로 크레딧을 충전할 때 소액의 결제 수수료를 더하는 구조입니다.
내가 실제로 얼마를 썼는지는 요청에 usage 옵션을 켜서 응답으로 바로 받아볼 수 있어요.
const completion = await client.chat.completions.create({
model: "anthropic/claude-sonnet-4",
messages: [{ role: "user", content: prompt }],
// @ts-expect-error usage는 OpenRouter 전용 옵션
usage: { include: true },
});
console.log(completion.usage); // 입력/출력 토큰과 비용(크레딧)
남은 크레딧이나 키 사용량은 /api/v1/auth/key 엔드포인트로도 확인할 수 있습니다. 대시보드에서는 모델별, 키별 사용량과 비용을 한 화면에서 비교할 수 있고요. 제공사가 여럿이어도 한곳에서 들여다본다는 게 리셀러의 가장 큰 장점이에요.
이미 OpenAI나 Anthropic 계정이 있어서 직접 결제 관계를 유지하고 싶다면, BYOK(Bring Your Own Key)도 지원합니다. 설정에서 제공사 키를 등록해두면 OpenRouter가 그 키로 대신 호출하고, 비용은 우리 제공사 계정에 직접 청구돼요. 이 경우 OpenRouter는 호출을 중개해주는 대가로 소액의 수수료만 가져갑니다. 키 관리와 단일 API의 편의는 누리되 결제 관계는 그대로 두고 싶을 때 유용한 절충안이죠.
게이트웨이, 리셀러, 그리고 OpenRouter
지금까지 본 OpenRouter를 비슷한 서비스와 나란히 놓으면 차이가 또렷해집니다. Cloudflare AI Gateway는 우리 키를 우리가 들고(BYOK) 그 길목에서 캐싱과 로그만 책임지는 프록시였어요. AWS Bedrock이나 Google Vertex AI는 한 클라우드 안에서 여러 모델을 묶어주지만, 그 생태계 바깥 모델까지 아우르진 않고요.
OpenRouter는 이들과 달리 제공사 중립적인 리셀러입니다. 특정 클라우드에 묶이지 않고, 키 하나로 OpenAI부터 오픈소스 모델까지 가장 넓게 부를 수 있다는 게 강점이에요. 대신 우리 요청과 데이터가 OpenRouter를 한 번 거친다는 점, 그리고 캐싱 같은 인프라 제어는 게이트웨이만큼 세밀하지 않다는 점은 감안해야 합니다. 그래서 실제로는 둘을 겹쳐 쓰기도 해요. 모델 선택의 폭은 OpenRouter로 넓히고, 캐싱과 모니터링 같은 운영은 그 앞단의 게이트웨이로 챙기는 식으로요.
결국 무엇을 고르느냐는 우리가 무엇을 위임하고 싶은지에 달렸습니다. 인프라 제어가 중요하면 프록시, 가장 넓은 모델 선택과 단일 결제가 중요하면 OpenRouter 같은 리셀러가 어울려요.
마치며
지금까지 OpenRouter를 첫 호출부터 모델 이름 규칙, 프로바이더 라우팅, 모델 폴백, 비용 계량까지 살펴봤습니다. 핵심은 OpenRouter가 OpenAI 호환 API를 쓰는 제공사 중립 리셀러라는 점이에요. 그래서 기존 코드에서 baseURL과 키만 바꾸면 곧바로 수백 개 모델을 키 하나로 부를 수 있고, provider와 models 옵션으로 라우팅과 폴백까지 요청 한 번에 얹는 거죠.
여기서 한 걸음 더 나아가고 싶다면, 모델 호출 앞단에 캐싱과 속도 제한을 더하는 Cloudflare AI Gateway나, AI 기능을 프레임워크 핸들러 안으로 끌어들이는 Void AI를 함께 살펴보세요. AI 관련 다른 글이 궁금하다면 AI 태그에 모아두었습니다.
더 자세한 내용은 OpenRouter 공식 문서를 참고하세요.
This work is licensed under CC BY 4.0