문서

문서

사용량 API

요청을 보낸 API 키의 토큰 수와 비용을 조회합니다. 키 하나당 해당 키의 데이터만 제공되며, 다른 키의 데이터에는 접근할 수 없습니다. 자체 결제 대시보드, 월간 정산, 비용 알림에 활용하세요.

GET /v1/usage는 Authorization 헤더의 API 키에 대한 토큰 및 비용 집계 수치를 반환합니다. 일별 또는 시간별로 묶고, 선택적으로 모델별로 나눌 수 있습니다. 다른 키의 데이터를 읽을 권한은 없습니다. 그러려면 대시보드에 로그인하세요.

인증

사용량을 조회하려는 Kunavo API 키를 Bearer 토큰으로 전달하세요. 이 엔드포인트는 해당 키에 청구된 사용량만 반환하며, 다른 키의 데이터를 요청하는 매개변수는 없습니다.

키 하나당 프로젝트 하나로 관리하세요. 청구 대상 애플리케이션마다 별도의 API 키를 발급하는 방식을 권장합니다. 그러면 Kunavo 대시보드와 이 엔드포인트에서 자연스럽게 프로젝트별 집계가 이루어집니다. /app/keys에서 키를 관리하세요.

요청

매개변수필수기본값참고
start_dateyes—YYYY-MM-DD, UTC. 시작일과 종료일 모두 포함. 오늘(UTC) 이하여야 합니다.
end_dateyes—YYYY-MM-DD, UTC. 시작일과 종료일을 포함합니다. 오늘 이후 날짜는 오늘로 해석되며, 응답에는 사용된 end_date가 그대로 표시됩니다.
bucketnodayday, hour 중 하나.
group_byno(none)쉼표로 구분합니다. 지원 값: model. 생략하면 버킷당 한 행을 반환합니다.
기간 제한. bucket=day은 최대 90일, bucket=hour는 최대 7일까지 허용됩니다. 이를 초과하면 요청은 400 invalid_request_error를 반환하므로 여러 번 호출해 나누세요.
시간대. 버킷은 UTC 일/시간 기준으로 정렬됩니다. 다른 tz의 실제 현지 날짜 기준이 필요하다면 일별로 조회하고 클라이언트에서 경계 구간을 합치세요. 향후 tz= 매개변수를 통해 기존 필드를 변경하지 않고 서버에서 처리할 예정입니다.

예시

지난 30일간 모델 전체를 합산한 일별 합계:

usage_30d.sh
# Daily totals for the last 30 days
curl https://api.kunavo.com/v1/usage \
  -G \
  -H "Authorization: Bearer $KUNAVO_API_KEY" \
  --data-urlencode "start_date=2026-04-28" \
  --data-urlencode "end_date=2026-05-27"

(일, 모델) 조합당 한 행:

usage_by_model.sh
# Per-model daily breakdown — one row per (day, model)
curl https://api.kunavo.com/v1/usage \
  -G \
  -H "Authorization: Bearer $KUNAVO_API_KEY" \
  --data-urlencode "start_date=2026-05-01" \
  --data-urlencode "end_date=2026-05-27" \
  --data-urlencode "group_by=model"

Python — 기간 합계를 하나의 숫자로 계산:

usage_query.py
import os, datetime as dt, requests

today = dt.date.today()
start = today - dt.timedelta(days=29)  # last 30 days inclusive

r = requests.get(
    "https://api.kunavo.com/v1/usage",
    headers={"Authorization": f"Bearer {os.environ['KUNAVO_API_KEY']}"},
    params={
        "start_date": start.isoformat(),
        "end_date":   today.isoformat(),
        "group_by":   "model",
    },
    timeout=30,
)
r.raise_for_status()
body = r.json()

# body["data"] is one row per (day, model). Sum cost across the window:
total_usd = sum(float(row["cost_usd"]) for row in body["data"])
print(f"Spent ${total_usd:.4f} on key {body['api_key']['name']}")

응답

200 OK — 행 목록이 포함된 application/json입니다. 활동이 없는 버킷은 생략됩니다. 연속된 시계열이 필요한 경우 클라이언트에서 누락 구간을 채우세요.

response.json
{
  "object": "list",
  "api_key": {
    "id": "k_abc123",
    "name": "production",
    "prefix": "sk-kn-aZ8x"
  },
  "start_date": "2026-05-01",
  "end_date":   "2026-05-27",
  "bucket": "day",
  "data": [
    {
      "bucket_start": "2026-05-01T00:00:00.000Z",
      "model": "claude-sonnet-4-6",
      "requests": 1284,
      "errors": 7,
      "input_tokens": 1532890,
      "output_tokens": 245100,
      "cached_input_tokens": 980000,
      "cache_write_tokens": 12000,
      "web_search_requests": 0,
      "cost_usd": "3.452100"
    },
    {
      "bucket_start": "2026-05-01T00:00:00.000Z",
      "model": "gpt-5",
      "requests": 88,
      "errors": 0,
      "input_tokens": 42000,
      "output_tokens": 12300,
      "cached_input_tokens": 0,
      "cache_write_tokens": 0,
      "web_search_requests": 0,
      "cost_usd": "0.210400"
    }
  ]
}
필드유형의미
bucket_start문자열(ISO 8601, UTC)이 행이 집계하는 일 또는 시간의 시작 시점입니다.
modelstring모델 슬러그입니다. group_by=model인 경우에만 포함됩니다.
requestsnumber이 버킷에서 성공한 호출 수입니다.
errorsnumber오류/시간 초과/취소로 종료된 호출 수입니다. 청구되지 않습니다.
input_tokensnumber총 입력 토큰 수입니다(캐시 및 캐시 쓰기 하위 항목 포함).
output_tokensnumber총 출력 토큰 수입니다.
cached_input_tokensnumberinput_tokens 중 업스트림 프롬프트 캐시에서 제공된 하위 항목입니다.
cache_write_tokensnumber이 버킷에서 캐시에 기록된 토큰입니다(Anthropic만 해당하며 그 외에는 0).
web_search_requestsnumber서버 측 웹 검색 횟수입니다. 각각 토큰 비용에 추가로 청구됩니다. Claude 검색은 /v1/messages를 통해, GPT 모델에서 사용하는 OpenAI web_search 도구는 /v1/responses를 통해 처리됩니다(그 외에는 0).
cost_usdstring이 버킷에 대해 청구된 USD 금액이며 소수점 이하 6자리 정밀도입니다. 정밀도 유지를 위해 문자열로 제공됩니다. parseFloat()를 사용하면 안전하게 처리할 수 있습니다.
비용을 문자열로 제공하는 이유. 매우 작은 호출당 비용(캐시 사용이 많은 트래픽에서는 1센트의 10만분의 몇 수준)은 단순하게 문자열로 변환하면 IEEE-754에서 0으로 반올림됩니다. 전송 형식을 소수점 이하 6자리의 문자열로 유지하면 회계 코드에서 임의 정밀도로 파싱할 수 있습니다(예: Decimal()).

클라이언트 측 캐싱

엔드포인트는 Cache-Control: private, max-age=60를 설정합니다. 대부분의 클라이언트(브라우저, 세션을 사용하는 요청, 자체 HTTP 캐시)는 60초 동안 동일한 매개변수에 같은 응답을 반환합니다. 주기적으로 조회하는 대시보드에는 적합합니다. 최신 결과를 강제로 가져오려면 쿼리 문자열을 변경하거나(예: &_=ts 캐시 방지 값을 추가) 클라이언트 측에서 Cache-Control: no-cache를 전달하세요.

오류

상태코드시기
401authentication_errorBearer 키가 없거나 형식이 잘못되었거나 취소되었습니다.
400invalid_request_error잘못된 start_date/end_date 형식, 종료일이 시작일보다 앞서는 경우, 오늘 이후의 start_date, 버킷 제한을 초과하는 기간, 지원하지 않는 group_by 값.
500internal_errorDB에 연결할 수 없거나 예기치 않은 오류가 발생했습니다.

주의 사항

  • 삭제된 키. API 키를 취소하면 과거 사용량 행의 api_key_id 값이 null로 바뀌므로 이 엔드포인트에서 과거 합계를 더 이상 조회할 수 없습니다. 데이터는 대시보드의 계정 전체 집계 화면에 계속 남아 있습니다. 변경 불가능한 키별 감사 기록이 필요하다면 키를 취소하기 전에 데이터를 가져와 저장하세요.
  • 준실시간. 해당 호출이 완료된 뒤 몇 초 이내에 행이 반영됩니다. 지연 시간 상한은 보장되지 않습니다. 청구서와 정확히 맞춰야 한다면 분 단위로 조회하지 말고 하루에 한 번 전날 데이터를 조회하세요.
  • 비용은 청구된 금액입니다. 여기의 cost_usd는 지갑 원장에서 차감된 금액과 일치합니다. 청구에 설명된 max(catalog, upstream × markup) 하한이 이미 반영되어 있습니다. 이 응답에는 별도의 "도매" 금액이 없습니다.

다음 단계

  • 청구 및 원장 — 각 호출의 cost_usd가 이곳에 반영되기 전에 계산되는 방식입니다.
  • 인증 — 새 API 키 발급(프로젝트당 하나).
  • 대시보드 사용량 보기 — 동일한 데이터를 차트, 호출별 상세 보기, 모든 키를 합산한 계정 전체 집계와 함께 제공합니다.