요금 계산 방식
USD 원가 × 환율 × (1 + 마진)
요금은 두 단계로 정해집니다. 먼저 모델별 판매 단가(토큰 1개당 원)를 구하고, 그 다음 요청이 실제로 쓴 토큰 수를 곱합니다. 두 계산 모두 서버 코드에 한 벌만 있고, 대시보드·API 응답·원장이 전부 같은 값을 봅니다.
1단계 — 판매 단가
우리가 외부 provider 에서 사들이는 원가는 USD 로 표시됩니다. 이걸 원화 판매가로 바꾸는 식은 다음과 같습니다.
m = 1 + margin_pct / 100
krw_prompt = override_krw_prompt ?? usd_prompt × fx × m
krw_completion = override_krw_completion ?? usd_completion × fx × m
krw_cache_read = override_krw_cache_read ?? (usd_cache_read 가 없으면 krw_prompt × 0.1
있으면 usd_cache_read × fx × m)| 기호 | 뜻 | 현재 값 |
|---|---|---|
fx | 적용 환율 (1 USD 당 원) | 1,350 |
margin_pct | 마진율 (%) | 30 (전역 기본값) |
override_krw_* | 관리자가 직접 지정한 판매가 | 모델별로 있을 수도, 없을 수도 |
우선순위는 모델별 규칙 → 전역 기본 규칙 순입니다. 특정 모델에 마진이나 판매가가 따로 지정돼 있으면 그것이 이깁니다.
캐시 읽기 단가
업스트림이 캐시 읽기 단가를 알려주지 않는 모델이라면, 캐시 적중 토큰은 프롬프트 단가의 10% 로 계산합니다. 알려주는 모델이라면 그 값에 같은 환율·마진을 적용합니다.
캐시 쓰기 토큰은 기록만 하고 청구하지 않습니다. 업스트림이 이 값을 일관되게 돌려주지 않기 때문입니다.
반올림
- 단가는 소수점 12자리에서 한 번 반올림해 보관합니다.
- 그 다음 반올림은 요청 비용 6자리뿐입니다.
중간 단계에서 반올림하지 않기 때문에 토큰이 아무리 많아도 오차가 누적되지 않습니다.
예: 외부 모델 하나
원가가 프롬프트 $0.50 / 1M 토큰, 완성 $1.50 / 1M 토큰인 모델을 기본 마진 30% 로 팔면:
krw_prompt = 0.0000005 × 1350 × 1.3 = 0.000877500000 원/토큰 → ₩877.5 / 1M 토큰
krw_completion = 0.0000015 × 1350 × 1.3 = 0.002632500000 원/토큰 → ₩2,632.5 / 1M 토큰
krw_cache_read = 0.000877500000 × 0.1 = 0.000087750000 원/토큰 → ₩87.75 / 1M 토큰2단계 — 요청 비용
billable_prompt = prompt_tokens - cached_tokens
cost_raw = billable_prompt × krw_prompt
+ cached_tokens × krw_cache_read
+ completion_tokens × krw_completion
cost_krw = ROUND(cost_raw, 6)읽어둘 점 몇 가지:
cached_tokens는prompt_tokens안에 포함되어 옵니다. 그래서 프롬프트에서 빼고 캐시 단가로 다시 셉니다. 이중 과금이 아닙니다.- 추론 토큰(
reasoning_tokens)은 이미completion_tokens안에 들어 있습니다. 따로 더하지 않습니다. - 반올림은 마지막 한 번뿐입니다.
워크스루 — 외부 모델
위 단가로 프롬프트 1,200토큰(그중 200토큰 캐시 적중), 완성 800토큰인 요청 하나:
billable_prompt = 1200 - 200 = 1000
1000 × 0.0008775 = 0.877500
200 × 0.00008775 = 0.017550
800 × 0.0026325 = 2.106000
─────────────
cost_krw = 3.001050 원응답 헤더에 그대로 나옵니다.
X-MyIP-Cost-KRW: 3.001050
X-MyIP-Currency: KRW워크스루 — 로컬 GPU 모델
google/gemma-4-26b-a4b 와 lgai/exaone-4.0-32b 는 우리 GPU 에서 직접 돌아가고, 판매가가 직접 지정돼 있습니다.
| 항목 | 단가 | 1M 토큰 환산 |
|---|---|---|
| 프롬프트 | 0.000030 원/토큰 | ₩30 / 1M 토큰 |
| 완성 | 0.000150 원/토큰 | ₩150 / 1M 토큰 |
프롬프트 2,000토큰(캐시 없음), 완성 1,000토큰이면:
2000 × 0.000030 = 0.060000
1000 × 0.000150 = 0.150000
─────────────
cost_krw = 0.210000 원가입 보너스 1,000원만으로 이 크기의 요청을 4,700회 넘게 보낼 수 있습니다.
어디서 단가를 확인하나
GET /api/v1/models 응답의 pricing 객체가 곧 판매 단가입니다. 필드 이름과 문자열 인코딩은 OpenAI 호환 카탈로그 형식 그대로이고, 숫자의 단위만 원/토큰입니다.
curl -s "https://openrouter.myip.co.kr/api/v1/models" \
| jq '.data[] | select(.id=="lgai/exaone-4.0-32b") | {id, pricing}'{
"id": "lgai/exaone-4.0-32b",
"pricing": {
"prompt": "0.000030000000",
"completion": "0.000150000000",
"input_cache_read": "0.000003000000",
"input_cache_write": null,
"currency": "KRW"
}
}요청 하나의 청구액 대조하기
정산이 끝난 뒤 GET /api/v1/generation 으로 그 요청의 실제 청구액을 조회할 수 있습니다.
curl -s "https://openrouter.myip.co.kr/api/v1/generation?id=$GEN_ID" \
-H "Authorization: Bearer $MYIP_API_KEY" | jq '{total_cost, tokens_prompt, tokens_completion}'total_cost 는 원장에 기입된 금액과 정확히 같은 값입니다. gen-… 아이디는 응답 헤더 X-MyIP-Generation-Id 로 받습니다.
스트리밍 응답에서는 마지막 usage 청크에 비용이 실려 옵니다.
{
"usage": {
"prompt_tokens": 1200,
"completion_tokens": 800,
"total_tokens": 2000,
"cost": 3.00105,
"cost_details": { "upstream_inference_cost": 2.295 }
}
}스트리밍은 응답 헤더에 비용을 실을 수 없어(헤더는 첫 바이트 전에 나갑니다) 이 청크가 유일한 경로입니다. stream_options.include_usage 는 우리가 항상 켜서 업스트림에 보내므로 따로 지정하지 않아도 됩니다.
과금하지 않는 경우
| 상황 | 청구 |
|---|---|
| 업스트림 오류로 실패한 요청 | 0원, 원장 기입 없음 |
| 프롬프트·완성 토큰이 모두 0 | 0원, 원장 기입 없음 |
| 사용자가 스트림을 중간에 끊음 | 그때까지 생성된 토큰만큼 청구 |
| 폴백 체인에서 첫 후보가 실패하고 두 번째가 성공 | 실제로 응답한 후보의 단가로 1회만 청구 |
단가가 바뀌면
환율과 마진, 모델별 판매가는 유효구간을 갖는 이력 테이블에 들어 있습니다. 값을 바꾸면 새 행이 생기고 이전 행은 닫힙니다. 과거 행은 수정되지 않습니다.
그리고 각 사용 기록에는 그 요청에 실제로 적용된 프롬프트 단가·완성 단가·환율·마진율이 함께 박제됩니다. 오늘 단가가 바뀌어도 어제 청구액이 어떻게 나왔는지 그대로 재현할 수 있습니다.
관련 문서
- 크레딧과 결제 — 충전, 영수증, 환불
- 사용 한도와 402 — 잔액이 떨어졌을 때
마지막 수정 2026. 9. 5.