개발 문서

Cafe24 LLM Router는 OpenAI SDK 호환 API를 제공합니다. 하나의 API Key로 OpenAI, Anthropic, Google, DeepSeek 등 여러 프로바이더의 모델을 사용할 수 있습니다.

Authentication

API를 호출하려면 먼저 API Key가 필요합니다.

1. API Key 발급

API 키 관리 페이지에서 키를 생성합니다. 키는 생성 시 한 번만 표시되므로 안전하게 저장하세요.

항목설명
Key 형식sk-cafe24- + 64자 hex (총 74자)
Base URLhttps://llm-router.cafe24.com
API 경로/api/v1/*
인증 방식Authorization: Bearer sk-cafe24-YOUR_KEY
적용 범위/api/v1/* 모든 엔드포인트에 필요합니다 — 모델 목록 조회(GET /api/v1/models) 포함

2. 연결 테스트

curl https://llm-router.cafe24.com/api/v1/models \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY"

Quick Start

API Key가 준비되었으면 Chat Completion을 호출합니다.

curl https://llm-router.cafe24.com/api/v1/chat/completions \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "deepseek-ai/DeepSeek-V3.1", "messages": [{"role": "user", "content": "Hello!"}], "stream": true }'
from openai import OpenAI client = OpenAI( base_url="https://llm-router.cafe24.com/api/v1", api_key="sk-cafe24-YOUR_KEY", ) response = client.chat.completions.create( model="deepseek-ai/DeepSeek-V3.1", messages=[{"role": "user", "content": "Hello!"}], stream=True, ) for chunk in response: print(chunk.choices[0].delta.content or "", end="")

Auto Routing

cafe24/auto 모델을 사용하면 프롬프트를 분석하여 코딩, 추론, 번역, 창작 등 task 유형을 자동 판별하고 최적 모델을 선택합니다.

curl https://llm-router.cafe24.com/api/v1/chat/completions \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "cafe24/auto", "messages": [{"role": "user", "content": "퀵소트를 파이썬으로 구현해줘"}] }'
response = client.chat.completions.create( model="cafe24/auto", messages=[{"role": "user", "content": "퀵소트를 파이썬으로 구현해줘"}], ) print(response.model) # 실제 선택된 모델
ParameterTypeDefaultDescription
cost_quality_balancestring"balanced""quality" 품질 우선 | "balanced" 균형 | "cost" 비용 우선
model_poolstring[]null후보 모델 제한. 예: ["deepseek-ai/*", "Qwen/Qwen3*"]

Allowed Models (Account 영구 설정)

매 요청에 model_pool을 보내는 대신, 라우팅 설정Allowed Models 필드에 와일드카드 패턴을 저장하면 모든 cafe24/auto 호출에 자동 적용됩니다 (per-request model_pool이 없을 때).

적용 범위

Auto Router 관련 설정 (cost_quality_balance, model_pool, Account의 allowed_models)은 cafe24/auto 모델로 호출했을 때만 적용됩니다. 다른 모델 (Qwen/Qwen3-32B, deepseek-ai/DeepSeek-V3.1 등) 호출 시에는 무시됩니다.

응답

HTTP케이스응답
200정상 자동 선택응답 model에 실제 선택된 모델 ID + extra_fields.resolved_model_used 포함
400model_pool/Allowed Models 패턴이 모든 모델을 제외 (0건 매칭){"error":{"code":"invalid_request","message":"Auto Router: 조건을 만족하는 모델이 없습니다 (category=..., patterns=[...])","param":"model_pool"}}

Provider Routing

요청의 provider 객체로 프로바이더 선택을 제어합니다. 설정은 3-layer로 머지됩니다: Account < Preset < Request (request 최우선).

"provider": { "order": ["deepinfra", "siliconflow"], "allow_fallbacks": false }
FieldTypeDescription
orderstring[]프로바이더 시도 순서. 예: ["deepinfra", "siliconflow"]
onlystring[]이 프로바이더만 허용 (화이트리스트)
ignorestring[]이 프로바이더 제외 (블랙리스트)
allow_fallbacksbooleanfallback 허용. 기본 true
sortstring"price" | "throughput" | "latency"

API(/api/v1) 요청에서 해석되는 provider 필드는 위 5개뿐입니다. max_price, data_collection, require_zdr, require_parameters, quantizations, preferred_min_throughput, preferred_max_latency 를 함께 보내도 요청은 정상 처리되지만 해당 조건은 적용되지 않습니다 — 비용 상한이나 ZDR 이 걸린 것으로 기대하고 호출하지 마세요.


정책 우선순위 (3-layer)

Provider Routing 설정은 3개 layer로 머지됩니다. Account < Preset < Request (request가 최우선).

Layer설정 위치적용 범위
AccountWeb 라우팅 설정이 사용자의 모든 요청에 우선 적용
PresetWeb 프리셋 설정 · API preset field해당 preset 사용 요청에만 적용
RequestAPI 요청 body provider 객체해당 요청 1회에만 적용

쉽게 말하면

  • Account 는 큰 울타리입니다. 사용자 본인이 Web 설정에서 정한 정책이며, 모든 요청에 항상 먼저 적용됩니다.
  • Preset 과 Request 는 그 울타리 안에서 동작합니다. Account 가 차단한 provider 는 Preset 이나 Request 에서 다시 허용할 수 없습니다.
  • "무엇만 허용한다"(only) 는 가장 좁은 범위로 좁혀지고, "무엇을 차단한다"(ignore) 는 모두 합쳐서 차단합니다. 즉 안전한 방향으로 머지됩니다.
  • "어느 순서로 시도할지"(order), "무엇 기준으로 정렬할지"(sort) 같은 단일 값은 Request 가 명시한 값이 가장 우선합니다 (없으면 Preset, 없으면 Account 순).

필드별 Merge 규칙

Account / Preset / Request 가 모두 지정되어 있을 때 각 필드별 머지 동작입니다. 한 layer 만 지정되어 있으면 그 값이 그대로 사용됩니다.

FieldMerge 방식의미
ignore합집합 (Account ∪ Preset ∪ Request)어느 layer 에서든 차단하면 차단 — 가장 엄격한 차단 정책
only교집합 (Account ∩ Preset ∩ Request)모든 layer 에서 허용한 것만 사용 — 가장 좁은 허용 범위. 교집합이 빈 set 이면 호출 차단
order상위 layer 우선 (Request > Preset > Account, 비-null 값이 있는 가장 상위 layer 채택)Request 가 명시하면 Request 값. Request 가 명시 안 했고 Preset 명시했으면 Preset 값. 둘 다 없으면 Account
sort상위 layer 우선 (동일)price / throughput / latency
max_price상위 layer 우선 (동일)최대 단가
data_collection상위 layer 우선 (동일)deny 시 데이터 수집 provider 제외
require_parameters상위 layer 우선 (동일)필수 파라미터 목록
quantizations상위 layer 우선 (동일)허용 양자화 목록
preferred_min_throughput상위 layer 우선 (동일)최소 throughput
preferred_max_latency상위 layer 우선 (동일)최대 latency
allow_fallbacksRequest layer 값 (preset/account 무시)Request 에 미명시 시 fallback 기본값 적용
require_zdrOR (어느 layer 든 truetrue)Zero-Data Retention 강제 — 가장 강한 정책 적용

위 표는 머지 규칙이고, layer 별로 지정 가능한 필드는 다릅니다. Request layer (/api/v1 요청의 provider 객체)에서 해석되는 필드는 order·only·ignore·sort·allow_fallbacks 5개이고(위 Provider Routing 참고), 계정 단위 설정으로 저장되는 값은 only·ignore·sort 입니다.

시나리오 예시

실제 사용 상황에서 각 layer 의 설정이 어떻게 합쳐지는지 보여드립니다.

상황AccountPresetRequest최종 결과
ignore 합집합ignore=[deepinfra]ignore=[siliconflow]ignore=[deepinfra, siliconflow]
only 교집합 — 결과 있음only=[deepinfra, siliconflow]only=[deepinfra]only=[deepinfra]
only 교집합 — 결과 빈 setonly=[siliconflow]only=[deepinfra]교집합 빈 set → 호출 차단 (403)
order 덮어쓰기order=[siliconflow, deepinfra]order=[deepinfra]order=[deepinfra] (Preset 이 Account 덮어씀)
order + sort 동시 (Preset/Request 다른 필드)order=[deepinfra]sort="price"order=[deepinfra] + sort="price" (필드별 독립 머지)
require_zdr ORrequire_zdr=falserequire_zdr=truerequire_zdr=true (어느 한 쪽이라도 true)
핵심 정리
  • Account 가 정한 정책은 절대 우회되지 않습니다.
  • Preset 과 Request 는 그 안에서 추가로 좁히거나 다른 필드를 더할 수 있을 뿐입니다.
  • 의도치 않게 차단된다면 먼저 Account 의 ignore / only 설정을 확인해보세요.

모든 라우팅 설정의 우선순위 — 한눈에

Provider 객체 머지 외에도 모델 선택, 화이트리스트, BYOK, 키 선택, 캐시 등 다양한 설정이 서로 다른 위치에서 결정됩니다.
각 설정이 어디서 정해지고, 충돌 시 무엇이 이기는지를 한눈에 정리했습니다.

설정결정 위치우선순위 / 머지빈 set / 충돌 시
Model
(단일 모델)
Preset.model
· Request model
Preset 이 model 을 지정하면
Request 의 model 무시 (override)
둘 다 미지정 시 400
Models
(fallback 후보 배열)
Request models[]
· Preset.fallback_models
Request 배열 먼저 시도
→ Preset fallback_models append (dedupe)
빈 배열이면 단일 모델만 시도
Provider 객체
(12 필드)
Account
· Preset
· Request
위 "필드별 Merge 규칙" 표 참조
(필드별 합집합 / 교집합 / 덮어쓰기)
only 교집합 빈 set → 403
Suffix
(:thinking, :floor)
Request 모델명 뒤 suffix암묵 provider prefs 제공 (sort=price 등)
explicit Account/Preset/Request prefs 가 있으면 무시
(빈 필드만 채움)
해당 모델이 suffix 미지원 시 무시
모델 ID 형식
(provider/model 표기)
Request model 문자열 전체/ 포함 전체가 모델 ID
(prefix 를 provider 로 해석 안 함)
미등록 모델 ID → 404 model_not_found
Allowed Models
(모델 화이트리스트)
API Key.allowed_models
· Group.allowed_models
교집합
(둘 다 허용해야 사용 가능)
NULL = 제약 없음
교집합 빈 set → 호출 거부
Auto Router
(cafe24/auto)
Account routing_config
(autoroute pool patterns)
Account 의 pool patterns 만 적용
Preset / Request override 없음
pool 빈 set → 400
(Auto Router: 조건을 만족하는 모델이 없습니다)
BYOK 키 선택User.byok_config
(사용자가 등록한 외부 provider 키)
등록된 provider 호출 시 자동 선택
Account/Preset 라우팅 설정과 무관
BYOK 복호화 실패 시 system 키로 fallback
(fail-open)
System 키 선택
(Two-Tier)
Group.provider_keys
(관리자 등록)
remaining > 0 필터
remaining 최다 키
→ 모두 0이면 Least-Used
Account/Preset 무관
활성 키 0개 → ProviderError
Fallback 동작Account · Preset · Request 의 allow_fallbacksRequest layer 값 사용
(Preset/Account 무시)
기본 true
401 / 403 / 인증 오류는 non-retryable
(fallback skip)
Rate Limit
(RPM/RPD)
API Key.rate_limitAPI Key 단위만
Group/Account override 없음
한도 초과 → 429
Budget
(월간 KRW/토큰)
API Key.budgetAPI Key 단위만한도 초과 → 429
(budget_exceeded_error)
Semantic CacheAdmin 강제
∧ API Key 토글
∧ 본문 저장 ON
∧ Privacy Filter(request_response_masking) OFF
∧ PII 마스킹(log_masking, 기본 ON) OFF
네 조건 모두 만족할 때만 활성
하나라도 부정이면 자동 비활성
비활성 시 cache miss 처리
(LLM 호출 진행)
Cache Sharing
(그룹 캐시 공유)
Group.cache_sharing_enabledGroup 단위 정책
API Key 토글 불가
OFF 시 API Key 별 격리 캐시만 사용
Privacy Filter
(request_response_masking)
관리자 강제 (admin endpoint)User-level 토글 불가
ON 시 본문 마스킹 + cache 자동 OFF
OFF (default) 시 원문 그대로
Body 저장
(store_request_response)
User.store_request_response
(본인 토글)
User-level
OFF 시 본문 미적재 + cache 자동 OFF
OFF 시 로그 상세에서 "(저장 안 함)"
BYOK 정책
(free_quota / fee_rate)
Admin (전역 admin_settings)모든 user 동일 적용
user 별 override 없음
월 호출수 한도 초과 시
호출 단위 fee 적용
정책 영역 구분 요약
  • 3-layer 머지 영역 (Account / Preset / Request 모두 영향)
    → Provider 객체 12 필드만 해당
  • Preset override 영역
    → Model (Preset.model 이 Request.model 우선) · Models (Request 배열 + Preset.fallback_models append)
  • API Key / Group 단위 영역 (Preset / Request 영향 없음)
    → Allowed Models, BYOK 키 선택, System 키 선택, Rate Limit, Budget, Cache Sharing
  • Account / User 단위 영역
    → Auto Router pool, Body 저장, BYOK 등록 키
  • Admin 강제 영역
    → Privacy Filter, BYOK 정책 (free_quota / fee_rate), Semantic Cache 글로벌 ON/OFF

모델 ID 형식

cafe24 LLM Router 는 모델 문자열 전체를 그대로 모델 ID 로 사용합니다. 모델 ID 에 / 가 포함돼 있어도(예: deepseek-ai/DeepSeek-V3.1) 그 전체가 하나의 모델 ID 이며,/ 앞부분을 provider 로 해석하지 않습니다. GET /api/v1/models 가 반환한 id 를 그대로model 필드에 넣으면 됩니다.

{ "model": "deepseek-ai/DeepSeek-V3.1" }

Provider 선택은 provider 객체로

특정 provider 로 강제하거나 우선순위를 두려면 모델 prefix 가 아니라 위 Provider Routingprovider 객체(order / only / ignore)를 사용합니다. 동일 모델을 여러 provider 가 제공할 때(예: deepseek-ai/DeepSeek-V3.1deepinfra·siliconflow모두 제공) 그중 하나를 선택할 수 있습니다.

{ "model": "deepseek-ai/DeepSeek-V3.1", "provider": { "only": ["siliconflow"] } // siliconflow 로 강제 }

존재하지 않는 모델

/api/v1/models 목록에 없는 모델 ID 를 호출하면 404 model_not_found 를 반환합니다. 이는 시맨틱 캐시 hit 으로도 우회되지 않습니다.

Reserved Model ID

cafe24/auto/ 가 있지만 모델 ID 가 아니라 Auto Router 트리거입니다. 모델 매칭 대신 자동 선택 라우팅으로 동작합니다.

BYOK 모델 ID

BYOK(본인 키)로 호출할 때는 claude-sonnet-4-6 와 같은 형식의 prefix 없는 모델 ID 로만 호출 가능합니다. (anthropic/claude-sonnet-4-6 처럼 provider/ prefix 가 붙은 형식은 BYOK 경로에서 지원되지 않습니다.)

Fallback Chain

models 배열의 각 항목도 동일하게 모델 ID 전체로 지정합니다. 앞 모델이 실패하면 다음으로 전환됩니다.

{ "model": "deepseek-ai/DeepSeek-V3.1", "models": [ "deepseek-ai/DeepSeek-V3.1", "Qwen/Qwen3-32B", "Qwen/Qwen3-8B" ] }

Model Features

Model Suffix

모델 ID 뒤에 :suffix를 붙여 동작을 변경합니다.

SuffixExampleEffect
:floordeepseek-ai/DeepSeek-V3.1:floor가장 저렴한 프로바이더 우선
:nitrodeepseek-ai/DeepSeek-V3.1:nitro가장 빠른 프로바이더 우선
:thinkingQwen/Qwen3-32B:thinking추론 모드 활성화
:freeQwen/Qwen3-8B:free무료 프로바이더 우선 (없으면 기본 라우팅)

Model Fallback

model 필드와 함께 models 배열로 순차 시도할 모델 체인을 지정합니다. 첫 모델이 실패하면 다음 모델로 자동 전환됩니다. model 필드는 필수이며, models만 단독 사용은 불가합니다.

{ "models": ["deepseek-ai/DeepSeek-V3.1", "Qwen/Qwen3-8B", "deepseek-ai/DeepSeek-V3.2"], "messages": [{"role": "user", "content": "Hello"}] }

Sticky Routing

동일 대화를 같은 프로바이더로 라우팅하여 KV 캐시를 활용합니다. Multi-turn 대화 시 자동 적용됩니다.


Presets

프리셋은 모델 + 프로바이더 라우팅 + 샘플링 파라미터를 하나의 설정으로 묶어 재사용하는 기능입니다. 수정 시 자동으로 버전 스냅샷이 저장됩니다.

프리셋 사용 (3가지 방법)

MethodExampleDescription
@preset/"model": "@preset/fast-coding"프리셋의 모델과 설정 모두 적용
Model override"model": "Qwen/Qwen3-32B@preset/fast-coding"모델만 변경, 나머지 프리셋 적용
preset field"preset": "fast-coding"별도 필드로 프리셋 지정

요청 파라미터가 프리셋 값을 오버라이드합니다. 프리셋 설정 페이지에서 UI로 생성하거나 API로 직접 관리합니다.


Semantic Cache

동일하거나 유사한 요청에 대해 캐시된 응답을 반환하여 비용을 절감하고 응답 속도를 높입니다.

설정위치설명
API Key별 ON/OFFAPI 키 관리 페이지키별 캐시 활성화/비활성화 + 유사도 임계값 (0.70~0.99)
요청별 제어요청 body"cache": {"semantic": false}로 개별 요청 캐시 비활성화

우선순위

API Key OFF > 요청 OFF > API Key 설정 > 글로벌 기본값. API Key에서 OFF한 경우 요청에서 ON할 수 없습니다.

캐시 스코프

시맨틱 캐시는 모델 단위로 동작합니다. 동일 model_id는 호출 형식 (bare 또는 prefix)과 무관하게 동일 캐시를 공유하여 효율을 극대화합니다. 같은 모델은 어느 provider가 제공하든 응답이 본질적으로 동일하기 때문입니다.

모델 ID 와 캐시

캐시는 모델 ID 단위로 동작합니다:

  • 유효한 모델 ID → 모델 단위 캐시 정상 hit (caching 효율 유지)
  • 미등록 모델 ID (예: Qwen/Qwen3-NotExist) → 캐시 lookup 전 차단되어 404 model_not_found

즉 잘못된 모델 ID 호출이 캐시 hit 으로 silently 성공하는 일은 없습니다.

캐시 엔트리는 캐시 관리 페이지에서 조회/삭제할 수 있습니다.


Metadata

요청에 metadata를 포함하면 사용량을 팀, 프로젝트, 환경 등으로 분류하여 추적할 수 있습니다. 프로바이더에 전달되지 않으며 로그에만 저장됩니다.

curl https://llm-router.cafe24.com/api/v1/chat/completions \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "Qwen/Qwen3-8B", "messages": [{"role": "user", "content": "Hello"}], "metadata": {"team": "backend", "project": "api-server", "env": "prod"} }'
response = client.chat.completions.create( model="Qwen/Qwen3-8B", messages=[{"role": "user", "content": "Hello"}], extra_body={"metadata": {"team": "backend", "project": "api-server"}}, )

사용 현황에서 metadata key-value 조합별 사용량을 집계할 수 있습니다.


Request/Response Body 저장

계정 단위 요청/응답 본문 저장 정책을 본인이 직접 토글합니다. default OFF — 디버깅이 필요할 때만 ON 으로 변경하세요. 본문 저장 OFF 상태에서는 시맨틱 캐시도 자동 비활성화됩니다.

항목설명
적용 범위계정 단위 — 본인이 발급한 모든 API Key 에 일괄 적용
기본값OFF — 본문이 저장되지 않음. 메타데이터/토큰/비용/모델명은 정상 적재
설정 방법프라이버시 설정 페이지 상단의 “Prompt / Response 데이터 관리” 카드에서 ON/OFF 토글
관리자 강제 OFF민감 데이터/컴플라이언스 사유로 관리자가 계정 단위 비상 OFF 가능 (audit 기록)
시맨틱 캐시본문 저장 OFF 면 시맨틱 캐시도 자동 OFF (semantic_cache_entries 가 raw 본문 저장)
보관 기간 (retention)저장된 본문의 보관 일수 — 7 / 14 / 30(기본)일 중 선택. 경과 시 자동 삭제
전환 시점OFF 토글 후 최대 300초 안에 모든 키에 반영 (Redis auth cache 만료)

Privacy Filter

LLM 호출 직전 요청 내용 중 민감정보(PII)만 식별해 마스킹 후 프로바이더로 전송하는 기능입니다. 본문 저장 정책과는 독립적으로 동작하지만, 마스터 스위치가 ON 이면 시맨틱 캐시는 자동 비활성화됩니다. 프라이버시 설정 페이지에서 룰을 관리합니다.

항목설명
적용 시점LLM 호출 직전 사용자 요청 내용
처리 방식REDACT 룰: 매칭 부분만 마스킹/치환 후 전송. BLOCK 룰: 매칭 시 요청 전체를 403 guardrail_blocked 로 차단
마스터 ON/OFF관리자 강제 (request_response_masking, user 토글 불가). 단 PII 카테고리/커스텀 룰은 사용자가 직접 관리
설정 위치Privacy Filter 페이지 — 사용자가 직접 룰 추가/수정/삭제
본문 저장과 관계본문 저장 정책과는 독립 (저장 ON/OFF 무관하게 동작)
시맨틱 캐시와 관계마스터 ON 시 시맨틱 캐시 자동 OFF (마스킹된 본문은 캐시 대상 제외)

Base URL: https://llm-router.cafe24.com/api/v1

Models

GET/api/v1/models
사용 가능한 모델 목록. cafe24/auto 포함. 모델당 1개 항목(id 유일)이며, 같은 모델을 여러 프로바이더가 서빙하면 한도(max_context_tokens/max_output_tokens)는 가장 낮은 값으로 표기하고 프로바이더별 원값은 providers 배열에 담깁니다.
GET/api/v1/models/{model_id}
단건 조회. 슬래시가 들어간 모델 ID도 그대로 붙입니다 (예: /api/v1/models/google/embeddinggemma-300m).

Response — data[] 항목

FieldTypeDescription
idstring호출에 쓰는 모델 ID. 목록 안에서 유일합니다.
owned_bystring대표 프로바이더 (providers 사전순 첫째).
max_context_tokens / max_output_tokensinteger여러 프로바이더가 서빙하면 가장 낮은 값. 어느 프로바이더로 가도 통과하는 한도입니다. 미신고면 null.
providersarray프로바이더별 원값 (name, max_context_tokens, max_output_tokens).
{ "object": "list", "data": [ { "id": "cafe24/auto", "object": "model", "owned_by": "cafe24", "max_context_tokens": null, "max_output_tokens": null }, { "id": "MiniMaxAI/MiniMax-M3", "object": "model", "owned_by": "deepinfra", "max_context_tokens": 524288, "max_output_tokens": 262144, "providers": [ { "name": "deepinfra", "max_context_tokens": 524288, "max_output_tokens": 262144 } ] } ] }

이 응답에는 모델 종류(chat·embedding·image·tts·stt·rerank)와 단가가 실리지 않습니다. 어떤 엔드포인트에 쓸 모델인지와 가격은 Models 페이지에서 확인하세요.cafe24/auto 는 프로바이더가 정해져 있지 않아 providers 가 없습니다.


Chat Completions

POST/api/v1/chat/completions
OpenAI 호환 Chat Completion. 스트리밍, Auto Routing, Preset, Provider Routing, Fallback, Function Calling, Vision 지원.
curl https://llm-router.cafe24.com/api/v1/chat/completions \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "deepseek-ai/DeepSeek-V3.1", "messages": [{"role": "user", "content": "Hello!"}], "max_tokens": 100, "stream": true }'
response = client.chat.completions.create( model="deepseek-ai/DeepSeek-V3.1", messages=[{"role": "user", "content": "Hello!"}], max_tokens=100, stream=True, )

응답의 extra_fields.routing_info실제로 요청을 처리한 프로바이더와 모델이 실려 옵니다 (provider, resolved_model_used, latency). cafe24/auto 나 Preset 처럼 모델이 런타임에 정해지는 경우 어디로 나갔는지 확인할 수 있습니다. 이 필드는 Embeddings · Rerank · Speech to Text 응답에도 함께 옵니다.


Responses

POST/api/v1/responses
OpenAI Responses API 호환. input/output 구조로 요청하고 받습니다.

지원 범위가 좁습니다. Responses 규격을 구현한 프로바이더의 OpenAI 계열 모델에서만 동작합니다. 그 밖의 모델은 아래처럼 거절되므로, 범용으로 쓸 경로가 필요하면 Chat Completions 를 쓰세요.

모델결과
gpt-4o, gpt-5, gpt-5-mini 등 OpenAI 계열정상
Anthropic 계열 (claude-*)400 — 이 경로에서 지원하지 않는다는 안내
그 밖 (예: gemini-*, solar-*)404 — 프로바이더가 이 규격을 제공하지 않음

Request Body

ParameterTypeDescription
modelstring필수. 위 지원 범위의 모델
inputstring | array필수. 입력 텍스트 또는 메시지 배열
instructionsstring시스템 프롬프트에 해당
max_output_tokensinteger최대 출력 토큰. 추론 모델은 이 예산을 추론에 먼저 씁니다 — 너무 작으면 본문 없이 status: "incomplete" 로 끝납니다
temperature · top_pnumber샘플링 파라미터
toolsarray도구 정의
streambooleanSSE 스트리밍
metadataobject요청 추적용 key-value. 프로바이더로 전달되지 않고 Activity 에서 확인합니다
curl https://llm-router.cafe24.com/api/v1/responses \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "gpt-4o", "input": "Say OK", "max_output_tokens": 32}'
response = client.responses.create( model="gpt-4o", input="Say OK", max_output_tokens=32, ) print(response.output_text)

Response

{ "id": "resp_009ee3bd52ff381b...", "object": "response", "status": "completed", "model": "gpt-4o", "output": [ { "type": "message", "role": "assistant", "status": "completed", "content": [ { "type": "output_text", "text": "OK!" } ] } ], "incomplete_details": null, "usage": { "input_tokens": 9, "output_tokens": 4, "total_tokens": 13 } }

Chat Completions 와 구조가 다릅니다 — 본문은 choices[].message.content 가 아니라 output[].content[].text 에 있고, 토큰 이름도 input_tokens · output_tokens 입니다. SDK 를 쓰면 response.output_text 로 바로 꺼냅니다. 끝까지 못 간 응답은 statusincomplete 이고 incomplete_details.reason 에 사유(예: max_output_tokens)가 실립니다. 이때도 소비한 토큰은 과금됩니다.


Embeddings

POST/api/v1/embeddings
텍스트를 벡터로 변환. 시맨틱 검색, 문서 유사도, RAG 인덱싱에 씁니다.
ParameterTypeDescription
modelstring필수. 임베딩 모델 (Models 에서 타입 Embedding 으로 필터)
inputstring | string[]필수. 임베딩할 텍스트. 배열로 여러 건을 한 번에 보낼 수 있습니다
dimensionsinteger출력 벡터 차원. 이를 지원하는 모델에서만 반영됩니다 (실측: google/embeddinggemma-300m256 을 주면 256차원이 옵니다)
encoding_formatstringfloat(기본) 또는 base64. base64 를 주면 embedding 이 숫자 배열이 아니라 base64 문자열로 옵니다
metadataobject요청 추적용 key-value
curl https://llm-router.cafe24.com/api/v1/embeddings \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "google/embeddinggemma-300m", "input": ["안녕하세요", "hello world"] }'
response = client.embeddings.create( model="google/embeddinggemma-300m", input=["안녕하세요", "hello world"], ) print(len(response.data[0].embedding)) # 768

Response

{ "object": "list", "model": "google/embeddinggemma-300m", "data": [ { "object": "embedding", "index": 0, "embedding": [0.012, -0.034, ...] } ], "usage": { "prompt_tokens": 7, "total_tokens": 7 } }

data 는 입력 순서대로 오고 index 로도 확인할 수 있습니다.벡터 차원은 모델마다 다릅니다 (실측: google/embeddinggemma-300m 은 768). 저장소 스키마를 잡기 전에 실제 응답 길이를 확인하세요. 과금은 입력 토큰 기준이며 출력 벡터 크기와 무관합니다.


Images

POST/api/v1/images/generations
텍스트 프롬프트로 이미지 생성.
POST/api/v1/images/edits
기존 이미지를 프롬프트로 편집. multipart/form-data 와 JSON(base64) 둘 다 받습니다.

Request Body

ParameterTypeDescription
modelstring필수
promptstring필수. 생성·편집 지시
imagefile | string/images/edits 전용, 필수. multipart 파일 또는 JSON 의 base64 data URL
maskfile | string/images/edits 전용. 편집 영역 마스크 (지원 모델 한정)
ninteger생성 장수 (기본 1). 장당 과금이라 이 값에 비례해 과금됩니다. 다만 모델이 무시할 수 있습니다 — 실측에서 stabilityai/sdxl-turbo 는 2장을 주지만 google/nano-banana-2-liten: 2 에도 1장만 돌려줍니다
sizestring"1024x1024" 형태. 해상도를 정하는 파라미터입니다
metadataobject요청 추적용 key-value. 프로바이더로 전달되지 않고 Activity 에서 확인합니다
curl https://llm-router.cafe24.com/api/v1/images/generations \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "stabilityai/sdxl-turbo", "prompt": "a small red apple on a white table", "n": 1, "size": "512x512" }'
curl https://llm-router.cafe24.com/api/v1/images/edits \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -F image=@original.jpg \ -F prompt="make the apple green" \ -F model=google/nano-banana-2-lite
curl https://llm-router.cafe24.com/api/v1/images/edits \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "google/nano-banana-2-lite", "prompt": "make the apple green", "image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..." }'

Response

{ "created": 1787711991, "data": [ { "b64_json": "/9j/4AAQSkZJRgABAQ..." } ] }

b64_jsonurl 중 무엇이 올지는 모델이 정합니다 — 실측에서 stabilityai/sdxl-turbo · google/nano-banana-2-lite b64_json, 일부 편집 모델은 만료되는 임시 url 을 줍니다. 두 키를 모두 확인하고, url 은 받은 즉시 내려받아 보관하세요. base64 는 선두 바이트로 실제 포맷을 판별하는 편이 안전합니다 (/9j/ = JPEG, iVBORw0 = PNG).

response_format 은 보내지 마세요. 반환 형태는 위처럼 모델이 정하며, 값을 지정하면 프로바이더가 거절할 수 있습니다 — 실측에서 stabilityai/sdxl-turbo response_format: "url" 을 주면 422 가 납니다.

이미지 응답에는 usage 가 없습니다 — 현재 제공하는 이미지 모델은 전부 장당 과금이라 토큰 집계가 없습니다. 비용은 Activity usage_krw_micro 로 확인하세요 (그 행의 토큰 값은 0 입니다).

모든 이미지 모델이 편집을 지원하지는 않습니다. 지원하지 않는 모델로 /images/edits 를 호출하면 프로바이더가 404 를 돌려줍니다. 편집 입력이 2장 이상이면 multipart 파일 필드명이 image[] 가 됩니다 (1장이면 image).


Rerank

POST/api/v1/rerank
질의와 문서 목록을 받아 관련도 순으로 재정렬. RAG 검색 결과 정제에 씁니다.

벡터 검색으로 넓게 뽑은 뒤 이 API 로 좁히면 LLM 에 넣는 문서 수를 줄일 수 있습니다.

ParameterTypeDescription
modelstring필수. rerank 모델
querystring필수. 기준이 되는 질의
documentsstring[] | object[]필수. 재정렬할 문서. 문자열 배열과 [{"text": "..."}] 형식 둘 다 받습니다
top_ninteger상위 N건만 반환. 미지정 시 전체
return_documentsbooleantrue 면 응답에 원문을 함께 실어 줍니다 (기본 false)
max_tokens_per_docinteger문서당 처리 토큰 상한. 프로바이더로 전달합니다
metadataobject요청 추적용 key-value
curl https://llm-router.cafe24.com/api/v1/rerank \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "Qwen/Qwen3-Reranker-0.6B", "query": "강아지 사료 추천", "documents": ["고양이 장난감 후기", "반려견 사료 비교 가이드", "노트북 리뷰"], "top_n": 2 }'
import requests r = requests.post( "https://llm-router.cafe24.com/api/v1/rerank", headers={"Authorization": "Bearer sk-cafe24-YOUR_KEY"}, json={ "model": "Qwen/Qwen3-Reranker-0.6B", "query": "강아지 사료 추천", "documents": ["고양이 장난감 후기", "반려견 사료 비교 가이드"], "top_n": 2, }, ).json() # index 는 보낸 documents 의 원본 위치다 for hit in r["results"]: print(hit["index"], hit["relevance_score"])

Response

{ "id": "01a03beeee177da6...", "model": "Qwen/Qwen3-Reranker-0.6B", "results": [ { "index": 1, "relevance_score": 0.9938, "document": { "text": "" } }, { "index": 0, "relevance_score": 0.0033, "document": { "text": "" } } ], "usage": { "prompt_tokens": 259, "total_tokens": 259 } }

results관련도 내림차순이고 index 는 보낸 documents 의 원본 위치입니다. return_documents 를 주지 않으면 document.text빈 문자열로 옵니다 — 키 자체는 오므로, 원문이 필요하면 index 로 되찾거나 return_documents: true 를 주세요. 과금은 질의와 문서를 합한 입력 토큰 기준입니다.


Text to Speech

POST/api/v1/audio/speech
텍스트를 음성으로 합성. 응답이 JSON 이 아니라 오디오 바이트입니다.

응답 본문이 원시 오디오 바이트라 파일로 그대로 저장하거나 플레이어에 바로 넘기면 됩니다 — .json() 으로 파싱하면 깨집니다.

ParameterTypeDescription
modelstring필수. TTS 모델
inputstring필수. 합성할 텍스트. 이 길이가 과금 기준입니다
voicestring음성 이름. 생략하면 프로바이더 기본 음성을 씁니다
response_formatstringmp3(기본) · opus · aac · flac · wav · pcm
speednumber재생 속도 배율. 프로바이더로 전달됩니다
instructionsstring톤·스타일 지시. 지원 모델에서만 반영됩니다
metadataobject요청 추적용 key-value
curl https://llm-router.cafe24.com/api/v1/audio/speech \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "hexgrad/Kokoro-82M", "input": "안녕하세요. 카페24 LLM Router 입니다.", "voice": "af_bella", "response_format": "mp3" }' \ --output speech.mp3
# 응답은 오디오 바이트다 — 스트리밍으로 파일에 바로 쓴다. with client.audio.speech.with_streaming_response.create( model="hexgrad/Kokoro-82M", input="안녕하세요. 카페24 LLM Router 입니다.", voice="af_bella", response_format="mp3", ) as response: response.stream_to_file("speech.mp3")
import { writeFile } from "node:fs/promises"; const res = await client.audio.speech.create({ model: "hexgrad/Kokoro-82M", input: "안녕하세요. 카페24 LLM Router 입니다.", voice: "af_bella", response_format: "mp3", }); await writeFile("speech.mp3", Buffer.from(await res.arrayBuffer()));

응답

본문은 오디오 바이트이고 포맷은 Content-Type 으로 알려 줍니다. 추적용 X-Request-ID 헤더도 함께 옵니다.

response_formatContent-Type
mp3 (기본)audio/mpeg
opus · aac · flac · wav · pcmaudio/opus · audio/aac · audio/flac · audio/wav · audio/pcm
그 밖의 값application/octet-stream

과금

  • 토큰이 아니라 input 의 문자 수로 과금됩니다. 한글 1자와 영문 1자는 같은 1자입니다.
  • 생성된 오디오 길이·파일 크기는 과금과 무관합니다 — speed 를 올려 짧게 만들어도 비용은 그대로입니다.
  • Activity 에서 이 호출의 토큰은 0 으로 기록됩니다. 비용은 usage_krw_micro 로 보세요.

Speech to Text

POST/api/v1/audio/transcriptions
오디오 파일을 텍스트로 변환. multipart/form-data 로 전송합니다.

JSON 이 아니라 multipart/form-data 로 보내야 하며, 파일은 26 MiB 까지 받습니다. 초과하면 요청이 거절됩니다.

FieldTypeDescription
filefile필수. 변환할 오디오 파일. 이 오디오의 길이가 과금 기준입니다
modelstring필수. STT 모델
languagestringISO-639-1 언어 코드 (ko, en 등). 지정하면 인식 정확도가 올라갑니다
promptstring고유명사·용어 힌트. 프로바이더로 전달됩니다
response_formatstring프로바이더로 전달됩니다. 지원 값은 모델마다 다릅니다
curl https://llm-router.cafe24.com/api/v1/audio/transcriptions \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" \ -F file=@sample.mp3 \ -F model=openai/whisper-large-v3-turbo \ -F language=ko
with open("sample.mp3", "rb") as f: result = client.audio.transcriptions.create( model="openai/whisper-large-v3-turbo", file=f, language="ko", ) print(result.text)

Response

{ "text": "안녕하세요. 카페24 LLM Router 입니다." }

과금은 오디오 길이(초) 기준이며 인식된 글자 수와 무관합니다. TTS 와 마찬가지로 Activity 의 토큰 값은 0 이고 비용은 usage_krw_micro 에 실립니다.


여기부터는 LLM 을 호출하는 API 가 아니라, 발급받은 키의 사용량을 조회하고 키를 관리하는 API 입니다. 사용량은 같은 데이터를 두 가지 형태(Usage·Activity)로 제공하며, 인증은 동일하게 API Key 를 씁니다.

Usage NEW

GET/api/v1/usage
이 API Key 의 사용량 조회. LLM 호출에 쓰는 키를 그대로 사용합니다. 관리 키로 호출하면 내 계정 전체 합산입니다.

날짜는 KST 기준이며 to 는 해당일을 포함합니다.

Query Parameters

ParameterTypeDefaultDescription
fromstring-시작일 (YYYY-MM-DD). 생략 시 조회 가능한 가장 이른 날
tostring오늘종료일 (YYYY-MM-DD). 해당일 포함
periodstringday버킷 단위. day · week · month · total
api_key_iduuid-관리 키 전용 필터 — 소유 키 하나로 좁히기 (비소유 404). 미지정 시 관리 키는 계정 전체, LLM 호출용 키는 자기 자신

Response

FieldTypeDescription
label, key_prefixstring키 이름 / 접두사
start_date, end_datestring실제 집계 구간 (KST)
requestsinteger요청 수
cached_requests, error_requestsinteger캐시 적중 / 실패 요청 수
prompt_tokens, completion_tokensinteger입력 / 출력 토큰
reasoning_tokens, total_tokensinteger추론 토큰 / 합계
cache_read_tokens, cache_creation_tokensinteger프롬프트 캐시 토큰
usagenumber비용 (KRW)
usage_krw_microinteger비용 (micro KRW). 정확한 정수값
usage_usdnumber | null비용 (USD). 참고값 — 아래 주의 참조
usd_completebooleanfalse 면 USD 단가 미등록 모델이 있어 usage_usd 가 과소
by_model[]array모델별 집계. model, model_requested, provider_name, 토큰, 비용
daily[]arrayperiod 버킷별 집계
data_completebooleanfalse 면 구간이 조정됐거나 일부 데이터만 포함
available_fromstring조회 가능한 가장 이른 날 (KST)
warningstring | null구간 조정 등이 발생한 경우의 설명
curl "https://llm-router.cafe24.com/api/v1/usage?from=2026-07-01&to=2026-07-31&period=day" \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY"
import requests res = requests.get( "https://llm-router.cafe24.com/api/v1/usage", params={"from": "2026-07-01", "to": "2026-07-31", "period": "month"}, headers={"Authorization": "Bearer sk-cafe24-YOUR_KEY"}, ) data = res.json()["data"] print(data["requests"], "requests", data["usage"], "KRW") # 모델별 비용 for m in data["by_model"]: print(m["model"], m["usage"])
{ "data": { "label": "my-api-key", "period": "day", "start_date": "2026-07-01", "end_date": "2026-07-31", "timezone": "Asia/Seoul", "currency": "KRW", "requests": 412, "prompt_tokens": 1840322, "completion_tokens": 92117, "usage": 11.83654, "usage_krw_micro": 11836540, "usage_usd": 0.00814548, "usd_complete": true, "by_model": [ { "model": "deepseek-ai/DeepSeek-V3.1", "model_requested": "cafe24/auto", "provider_name": "deepinfra", "requests": 210, "usage": 9.80 } ], "daily": [ { "date": "2026-07-31", "requests": 12, "usage": 0.41 } ], "data_complete": true, "available_from": "2026-05-03" } }

주의

  • 조회 범위는 최근 90일입니다. 더 이전을 요청해도 오류가 아니라 자동으로 조정되며, data_complete: falseavailable_from 으로 알려줍니다.
  • modelmodel_requested 가 다를 수 있습니다. cafe24/auto 나 별칭으로 호출하면 실제 선택된 모델이 model 에 들어갑니다.
  • 과금 기준은 KRW(usage_krw_micro)입니다. usage_usd 는 모델 USD 단가로 산출한 참고값이며, 단가 미등록 모델이 있으면 usd_complete: false 로 표시됩니다.
  • 조회 대상은 기본적으로 요청에 사용한 키 자신입니다. 예외로 관리 키로 호출하면 내 계정 전체 사용량이 합산되어 반환되고, api_key_id 파라미터로 소유 키 하나로 좁힐 수 있습니다 (비소유 키 지정은 404). 다른 사용자의 사용량은 어떤 경우에도 조회할 수 없습니다.
  • 요청 한도는 키당 분당 10회 · 하루 1,000회이며, /usage·/activity·/keys 호출을 합산해 셉니다 (키 생성·수정·삭제 같은 쓰기 요청 포함). 초과하면 429 를 반환합니다. LLM 호출 한도와는 별도 카운터입니다.
  • 위 표에 없는 쿼리 파라미터를 보내면 400 입니다 (지원하지 않는 쿼리 파라미터: …, 허용 목록 포함). 오타나 미지원 옵션이 조용히 무시된 채 다른 구간이 집계되는 일을 막기 위한 동작입니다.

Activity NEW

GET/api/v1/activity
API Key 사용량을 일자 × 모델 × 프로바이더로 집계. LLM 호출용 키로 인증하면 그 키 단독, 관리 키로 인증하면 내 계정 전체 합산입니다.

표준 activity 스키마와 필드 호환이라 기존 사용량 조회 클라이언트를 그대로 붙일 수 있습니다. 조회 대상은 기본적으로 인증에 쓴 키 자신입니다. 관리 키로 호출하면 내 계정 전체 사용량이 합산되고, api_key_id 로 소유 키 하나로 좁힐 수 있습니다 (비소유 키 지정은 404).

Query Parameters

ParameterTypeDescription
datestring단일 일자 (YYYY-MM-DD). from/to 와 함께 쓸 수 없습니다 (400).
fromstring시작일 (YYYY-MM-DD).
tostring종료일 (YYYY-MM-DD, 해당일 포함).
api_key_iduuid관리 키 전용 필터 — 소유 키 하나로 좁히기 (비소유 404). 미지정 시 관리 키는 계정 전체, LLM 호출용 키는 자기 자신.
timezonestring일자 경계 기준. Asia/Seoul(기본) 또는 UTC. KST·Etc/UTC 별칭도 받으며, 응답에는 정규 표기가 실립니다.
group_bystringmetadata:<key> 형식. 요청 시 보낸 metadata 값으로 한 축 더 분해합니다 (예: metadata:team).

셋 다 생략하면 최근 30일입니다. 보존 기간은 90일이며, 더 긴 구간이 필요하면 응답의 available_from 을 보고 from 을 지정하세요. 보존 기간을 벗어난 구간은 자동으로 잘리고 warning 으로 알립니다. 요청 구간 전체가 조회 범위 밖이면 400 입니다. 위 표에 없는 쿼리 파라미터를 보내도 400 입니다 (지원하지 않는 쿼리 파라미터: …, 허용 목록 포함) — 오타나 미지원 옵션이 조용히 무시된 채 다른 구간이 집계되는 일을 막기 위한 동작입니다.

Response — data[] 항목

FieldTypeDescription
datestring집계 일자 (timezone 기준).
modelstring실제 사용된 모델 (과금 기준).
provider_namestring프로바이더.
endpoint_idstring{provider}/{model} 합성값.
requestsinteger요청 수.
prompt_tokens / completion_tokens / reasoning_tokensinteger토큰 수.
usagenumberUSD 참고값 — 아래 주의사항 참조.
usage_krw_microinteger실제 청구 근거 (micro KRW, 1,000,000 = 1원).
usd_completebooleanfalse 면 USD 단가가 없는 모델이 섞여 usage 가 과소집계입니다.
metadata_key / metadata_valuestringgroup_by 를 준 요청에만 채워집니다. 미지정 시 null.

metadata 별 분해

요청 body 에 metadata 를 실어 보냈다면(Metadata 참조),group_by=metadata:<key> 로 그 키의 값별 사용량을 나눠 볼 수 있습니다. 기존 축(일자·모델·프로바이더)은 그대로 두고 한 축이 더해지는 형태입니다.

group_by 를 주지 않으면 응답 구조가 전혀 달라지지 않습니다. 기존 호환 클라이언트를 쓰고 있다면 이 파라미터를 보내지 않는 한 영향이 없습니다. metadata 없이 보낸 요청도 누락되지 않고 metadata_value 가 빈 문자열인 행에 모이므로, 분해 전후의 합계는 항상 같습니다.

Response — 최상위 필드

FieldDescription
start_date / end_date실제 집계된 구간 (클램프 적용 후).
available_from조회 가능한 가장 이른 일자.
data_completefalse 면 요청 구간 일부가 잘렸거나 데이터가 부분적입니다.
warning잘림·부분 데이터의 사람이 읽는 설명. null 이면 정상.

주의

금액은 usage_krw_micro 를 쓰세요. usage(USD)는 조회 시점의 단가로 환산한 참고값이라, 단가가 개정되면 같은 과거 구간을 다시 조회했을 때 값이 달라집니다.usage_krw_micro 는 호출 시점에 확정된 청구액이라 변하지 않습니다.

요청 한도는 키당 분당 10회 · 하루 1,000회이며, /usage·/activity·/keys 호출을 합산해 셉니다 (키 생성·수정·삭제 같은 쓰기 요청 포함). 초과하면 429 를 반환합니다. (LLM 호출 한도와는 별도 카운터입니다.)

# 최근 30일 (기본) curl https://llm-router.cafe24.com/api/v1/activity \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" # 특정 일자 curl "https://llm-router.cafe24.com/api/v1/activity?date=2026-08-01" \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" # 구간 지정 + UTC 기준 curl "https://llm-router.cafe24.com/api/v1/activity?from=2026-07-01&to=2026-07-31&timezone=UTC" \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY" # metadata 의 team 값별로 분해 curl "https://llm-router.cafe24.com/api/v1/activity?group_by=metadata:team" \ -H "Authorization: Bearer sk-cafe24-YOUR_KEY"
import requests r = requests.get( "https://llm-router.cafe24.com/api/v1/activity", headers={"Authorization": "Bearer sk-cafe24-YOUR_KEY"}, params={"from": "2026-07-01", "to": "2026-07-31"}, ).json() # 실제 청구액 합계 (원) total_krw = sum(i["usage_krw_micro"] for i in r["data"]) / 1_000_000 if not r["data_complete"]: print("주의:", r["warning"])

Management API NEW

관리 키(management key)로 API 키를 프로그래밍 방식으로 생성·조회·수정·삭제합니다. CI/온보딩 자동화에서 키를 발급하고, 위의 Usage 로 사용량을 함께 조회하는 식으로 씁니다. 관리 키는 콘솔 > 관리 키에서만 발급됩니다.

구분가능불가
관리 키/keys 생성·조회·수정·삭제, /usage·/activity (계정 전체 합산)LLM 호출 전부 403
LLM 호출용 키Chat 등 추론 + /usage·/activity/keys 호출 403
POST/api/v1/keys
LLM 호출용 키 생성. 응답의 key 원문은 이 응답에서만 1회 제공됩니다.
GET/api/v1/keys
내 키 목록. status=active|disabled 필터, limit/offset 페이징.
GET/api/v1/keys/{key_id}
키 단건 조회 (한도·리셋 주기·만료·활성 상태).
PATCH/api/v1/keys/{key_id}
키 수정 — 보낸 필드만 반영 (name, disabled, limit_krw, limit_reset).
DELETE/api/v1/keys/{key_id}
키 삭제 (즉시 무효화, 사용 이력은 감사 목적으로 보존).

생성 Body

FieldTypeDescription
namestring필수. 키 이름 (최대 100자)
limit_krwinteger지출 한도 (KRW 정수). 미지정 시 무제한
limit_resetstringdaily | weekly | monthlyKST 자정에 한도 사용액 초기화
expires_atdatetime만료 시각 (생성 시에만 지정 가능, 이후 변경 불가)
tagsobject키 태그 (key-value 객체)
group_namestring라우팅 그룹. 미지정 시 내 최신 활성 키의 그룹을 상속

키 객체

FieldTypeDescription
idstring키 식별자 (UUID). 수정·삭제 시 경로에 사용
keystring생성 응답에만 1회 포함되는 키 원문 (sk-cafe24-...)
key_prefixstring키 앞자리 (식별용)
key_typestringinference(LLM 호출용) | management
disabledboolean비활성 여부. PATCH 로 토글
limit_krw, limit_reset, last_limit_reset_at한도·리셋 주기·마지막 리셋 시각
expires_at, created_at, updated_atdatetime만료·생성·수정 시각
curl -X POST "https://llm-router.cafe24.com/api/v1/keys" \ -H "Authorization: Bearer sk-cafe24-YOUR_MANAGEMENT_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "team-a-key", "limit_krw": 50000, "limit_reset": "monthly", "tags": {"project": "TEAM-A"}}'
import requests # 키 발급 + 사용량 조회를 한 스크립트에서 (관리 키 / 발급된 키를 각각 사용) created = requests.post( "https://llm-router.cafe24.com/api/v1/keys", headers={"Authorization": "Bearer sk-cafe24-YOUR_MANAGEMENT_KEY"}, json={"name": "team-a-key", "limit_krw": 50000, "limit_reset": "monthly"}, ).json() print(created["key"]) # 원문은 이 응답에서만 — 안전한 곳에 보관 keys = requests.get( "https://llm-router.cafe24.com/api/v1/keys", headers={"Authorization": "Bearer sk-cafe24-YOUR_MANAGEMENT_KEY"}, ).json() for k in keys["data"]: print(k["name"], k["limit_krw"], k["disabled"])
{ "key": "sk-cafe24-0123abcd...", "id": "e40e885f-33df-458f-9d78-7d1db0ff14b7", "name": "team-a-key", "key_prefix": "sk-cafe24-0123abcd", "key_type": "inference", "disabled": false, "limit_krw": 50000, "limit_reset": "monthly", "expires_at": null, "created_at": "2026-09-02T06:23:47+00:00" }

주의

  • 키 원문은 생성 응답에서만 1회 제공됩니다. 다시 조회할 수 없습니다.
  • 생성되는 키는 항상 LLM 호출용(inference) 입니다 — 관리 키를 API 로 복제할 수는 없습니다 (발급은 콘솔에서만).
  • 수정(PATCH)에서 한도를 무제한으로 되돌리려면 clear_limit: true, 리셋 주기 해제는 clear_limit_reset: true 를 보내세요 (null 은 "미변경").
  • 일부 네트워크 경로에서 프록시가 PATCH 메서드를 차단해 405 가 날 수 있습니다 (대안 제공 검토 중). 이 경우 비활성/삭제는 DELETE 와 재발급으로 우회하세요.
  • 관리 키로 수행한 모든 생성·수정·삭제는 감사 기록으로 남고, 콘솔 > 관리 키의 활동 이력에 표시됩니다.
  • 관리 키로 Usage·Activity 를 호출하면 내 계정 전체 사용량 합산이 반환됩니다. 특정 키만 보려면 api_key_id 파라미터로 좁히세요. LLM 호출용 키로 호출하면 그 키 자신의 사용량만 나옵니다.
  • 요청 한도는 키당 분당 10회 · 하루 1,000회이며, /usage·/activity·/keys 호출을 합산해 셉니다 (키 생성·수정·삭제 같은 쓰기 요청 포함). 초과하면 429 를 반환합니다.
  • 요청 body 에 정의되지 않은 필드가 있으면 400 (Extra inputs are not permitted) 입니다. /usage·/activity 도 표에 없는 쿼리 파라미터를 400 으로 거부합니다 — 오타·미지원 옵션이 조용히 무시되지 않도록 의도된 동작입니다.

Request Parameters

POST /api/v1/chat/completions 요청 body 파라미터. 다른 엔드포인트도 공통 파라미터를 지원합니다.

Required

ParameterTypeDescription
modelstring모델 ID. "deepseek-ai/DeepSeek-V3.1", "cafe24/auto", "@preset/slug"
messagesarray메시지 배열. [{"role": "user", "content": "..."}]

Sampling

ParameterTypeDefaultDescription
temperaturenumber1.0랜덤성 (0~2)
top_pnumber1.0Nucleus sampling (0~1)
max_tokensinteger-최대 출력 토큰 수. 미지정 시 모델 기본값. 모델의 최대 출력 토큰을 넘으면 400
frequency_penaltynumber0반복 억제 (-2~2)
presence_penaltynumber0새 토픽 유도 (-2~2)
streambooleanfalseSSE 스트리밍
stopstring[]null생성 중단 토큰
seedintegernull재현성 시드
response_formatobjectnullJSON mode / Structured Outputs
logprobsbooleanfalse로그 확률 반환
top_logprobsintegernull상위 N개 로그 확률 (0~20)

Routing

ParameterTypeDescription
providerobject프로바이더 라우팅 설정
modelsstring[]Fallback 모델 체인
presetstring프리셋 slug
toolsarrayFunction calling 도구 정의
tool_choicestring | object도구 선택 전략. "auto", "none", 또는 {"type":"function","function":{"name":"..."}}
cost_quality_balancestringAuto Router 균형
model_poolstring[]Auto Router 후보 와일드카드
cacheobject캐시 제어. {"semantic": false}

Tracking

ParameterTypeDescription
metadataobject요청 추적용 key-value. 프로바이더에 전달되지 않음.

OpenAI 공식 SDK를 그대로 사용합니다. base_url만 LLM Router로 변경하면 됩니다. Anthropic·Google 등 다른 프로바이더의 모델도 GET /api/v1/models 가 반환한 모델 ID (예: anthropic/claude-opus-4-8)를 model 에 넣어 같은 SDK 로 호출합니다.

Python (OpenAI SDK)

OpenAI, Google, DeepSeek 등 OpenAI 호환 모델에 사용합니다.

pip install openai
from openai import OpenAI client = OpenAI( base_url="https://llm-router.cafe24.com/api/v1", api_key="sk-cafe24-YOUR_KEY", ) # Chat Completion response = client.chat.completions.create( model="deepseek-ai/DeepSeek-V3.1", messages=[{"role": "user", "content": "Hello!"}], ) print(response.choices[0].message.content) # Streaming stream = client.chat.completions.create( model="deepseek-ai/DeepSeek-V3.1", messages=[{"role": "user", "content": "Hello!"}], stream=True, ) for chunk in stream: print(chunk.choices[0].delta.content or "", end="") # Metadata, Provider Routing (extra_body) response = client.chat.completions.create( model="deepseek-ai/DeepSeek-V3.1", messages=[{"role": "user", "content": "Hello"}], extra_body={ "metadata": {"team": "backend"}, "provider": {"order": ["siliconflow"]}, }, )

Node.js (OpenAI SDK)

npm install openai
import OpenAI from 'openai'; const client = new OpenAI({ baseURL: 'https://llm-router.cafe24.com/api/v1', apiKey: 'sk-cafe24-YOUR_KEY', }); // Chat Completion const response = await client.chat.completions.create({ model: 'deepseek-ai/DeepSeek-V3.1', messages: [{ role: 'user', content: 'Hello!' }], }); // Streaming const stream = await client.chat.completions.create({ model: 'deepseek-ai/DeepSeek-V3.1', messages: [{ role: 'user', content: 'Hello!' }], stream: true, }); for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content || ''); }

curl

모든 엔드포인트를 curl로 직접 호출할 수 있습니다.

# 환경변수 설정 export LLM_ROUTER_URL="https://llm-router.cafe24.com" export LLM_ROUTER_KEY="sk-cafe24-YOUR_KEY" # Chat Completion curl $LLM_ROUTER_URL/api/v1/chat/completions \ -H "Authorization: Bearer $LLM_ROUTER_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "deepseek-ai/DeepSeek-V3.1", "messages": [{"role": "user", "content": "Hello"}]}' # Model List curl $LLM_ROUTER_URL/api/v1/models \ -H "Authorization: Bearer $LLM_ROUTER_KEY"