ドキュメント

ドキュメント

使用量 API

リクエストに使用されたAPI keyのトークン数と費用を照会します。1つのkeyから取得できるのはそのkey自身のデータのみで、他のkeyのデータにはアクセスできません。独自の請求ダッシュボード、月次照合、コストアラートに利用できます。

GET /v1/usageは、AuthorizationヘッダーのAPI keyのトークン数と費用の集計を返します。日別または時間別にグループ化し、必要に応じてモデル別に分けられます。他のkeyのデータを読み取る権限はありません。他のkeyのデータが必要な場合は、ダッシュボードにログインしてください。

認証

使用量を確認したいKunavo API keyをBearer tokenとして渡します。このエンドポイントが返すのは、この特定のkeyに対して請求された使用量のみです。他のkeyのデータを要求するパラメーターはありません。

プロジェクトごとに1つのkeyを使用してください。請求対象のアプリケーションごとに個別のAPI keyを発行することを推奨します。Kunavoのダッシュボードとこのエンドポイントで、自然に「プロジェクトごと」の集計ができます。keyは/app/keysで管理できます。

リクエスト

パラメーター必須デフォルト注記
start_dateyes—YYYY-MM-DD、UTC。開始日と終了日を含みます。今日(UTC)以前である必要があります。
end_dateyes—YYYY-MM-DD、UTC。両端を含みます。今日より後の日付は今日として読み取られ、レスポンスには使用されたend_dateが返されます。
bucketnodaydayまたはhourのいずれか。
group_byno(none)カンマ区切り。対応値:model。省略すると、バケットごとに1行返されます。
期間の上限。 bucket=dayは最大90日、bucket=hourは最大7日を指定できます。これを超えるとリクエストは400 invalid_request_errorを返します。複数回に分けて呼び出してください。
タイムゾーン。バケットはUTCの日/時に合わせられます。別のタイムゾーンの暦日単位で必要な場合は、日別に照会し、端の部分をクライアント側で集計してください。今後追加予定の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"

(日、モデル)ごとに1行:

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 — 期間内の値を合計して1つの数値にする:

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_startstring(ISO 8601、UTC)この行で集計される日または時間の開始時刻。
modelstringモデルのslug。group_by=modelの場合にのみ存在します。
requestsnumberこのバケット内で成功した呼び出しの数。
errorsnumberエラー/タイムアウト/キャンセルで終了した呼び出しの数。請求対象外です。
input_tokensnumber入力トークンの合計(キャッシュ分とキャッシュ書き込み分を含む)。
output_tokensnumber出力トークンの合計。
cached_input_tokensnumberinput_tokensのうち、上流のプロンプトキャッシュから提供された部分。
cache_write_tokensnumberこのバケットでキャッシュに書き込まれたトークン(Anthropicのみ。その他は0)。
web_search_requestsnumberサーバー側のWeb検索。トークン料金とは別に検索ごとに請求されます。Claudeの検索は/v1/messages経由、GPTモデル上のOpenAIのweb_searchツールは/v1/responses経由です(それ以外では0)。
cost_usdstringこのバケット分として請求された米ドル額。精度は小数点以下6桁です。精度を保つため文字列で返されます。parseFloat()を使えば安全に解析できます。
費用が文字列である理由。ごく小さな呼び出しあたりの費用(キャッシュ利用の多いトラフィックでは、1セントの10万分の1の数倍程度)は、単純に文字列化するとIEEE-754では0に丸められます。ワイヤ形式を小数点以下6桁の文字列にすることで、会計コードで任意精度(例:Decimal())を使って解析できます。

クライアント側のキャッシュ

このエンドポイントはCache-Control: private, max-age=60を設定します。ブラウザー、セッション付きリクエスト、お客様側のHTTPキャッシュなど、多くのクライアントは同じパラメーターへのレスポンスを60秒間キャッシュします。定期的にポーリングするダッシュボードには問題ありません。最新の値を取得するには、クエリー文字列を変更(例:&_=tsbusterを追加)するか、お客様側でCache-Control: no-cacheを渡してください。

エラー

ステータスコードいつ
401authentication_errorBearer keyがない、形式が不正、または無効化されています。
400invalid_request_errorstart_date/end_dateの形式が不正、終了日が開始日より前、start_dateが今日より後、期間がバケット上限を超過、または未対応のgroup_by値。
500internal_errorDBに接続できない、または予期しない障害が発生しました。

注意事項

  • 削除済みのkey。API keyを無効化すると、過去の使用量行からそのapi_key_idが失われ(nullに設定され)、このエンドポイントでは過去の合計を取得できなくなります。データはダッシュボードのアカウント全体の集計表示には残ります。変更できないkeyごとの監査記録が必要な場合は、無効化する前にデータを取得して保存してください。
  • ほぼリアルタイム。基となる呼び出しの完了から数秒以内に行が追加されます。古さの上限は保証されません。請求書と正確に照合する必要がある場合は、分単位ではなく、1日1回、前日分を照会してください。
  • 費用は請求額です。ここに表示されるcost_usdは、ウォレットの台帳から差し引かれた額と一致します。Billingに記載されているmax(catalog, upstream × markup)の下限がすでに反映されています。このレスポンスに別個の「卸売」価格はありません。

次に確認する項目

  • 請求と台帳 — 各呼び出しのcost_usdがここに反映される前にどのように計算されるか。
  • 認証 — 新しいAPIキーの発行(プロジェクトごとに1つ)。
  • ダッシュボードの使用量表示 — グラフ、呼び出しごとの詳細、すべてのkeyをまとめたアカウント全体の集計を含む同じデータ。