使用状況詳細のエクスポート
LMU AI 使用状況エクスポートガイド:ログインして JWT を取得し、ページネーション・期間指定・モデルフィルタリングに対応した /api/v1/usage を呼び出す。3 言語のサンプル付き。
アカウントとパスワードでログインして JWT を取得し、その JWT で /api/v1/usage を呼び出して、完全なトークン使用状況詳細テーブル(コンソールの /usage ページと同一) を取得します。
エクスポート・照合・エンタープライズ BI への読み込みを自動化する長時間実行のスクリプトに最適です。毎回手動で CSV をダウンロードする必要はありません。
なぜ sk-... API キーで直接取得できないのか? このキーはゲートウェイの業務コール(/v1/messages など)専用であり、アカウントレベルの詳細クエリを公開していません。これは意図的なセキュリティ設計です。キーが漏洩しても、請求全体がダンプされることを避けるためです。アカウントレベルのデータにはアカウント認証(JWT)を使用する必要があります。
1. API の概要
| 項目 | 値 |
|---|---|
| ベース URL | https://api.lmuai.com |
| 認証 | Authorization: Bearer <access_token>(アカウントログインで得た JWT) |
| アクセストークンの有効期間 | 86400 秒(24 時間)、refresh_token で更新可能 |
| レスポンス形式 | JSON。code: 0 は成功、失敗時は code != 0 で message フィールドあり |
| 推奨用途 | 請求エクスポートの自動化、エンタープライズ BI への読み込み、照合スクリプト |
2. ステップ 1 — ログインして JWT を取得する
POST /api/v1/auth/login
POST /api/v1/auth/login HTTP/1.1
Content-Type: application/json
{
"email": "your@email.com",
"password": "your-password"
}レスポンス(抜粋):
{
"code": 0,
"message": "success",
"data": {
"access_token": "eyJhbGc...",
"refresh_token": "rt_756a220ffa...",
"expires_in": 86400,
"token_type": "Bearer",
"user": { "id": 3, "email": "...", "balance": 1575.13 }
}
}以降のすべてのリクエストには Authorization: Bearer <access_token> を含めるだけです。
3. ステップ 2 — 使用状況詳細を取得する
GET /api/v1/usage
GET /api/v1/usage?page=1&page_size=200&start_date=2026-06-01&end_date=2026-06-23&timezone=Asia/Shanghai
Authorization: Bearer <access_token>クエリパラメータ
| パラメータ | 型 | 必須 | デフォルト | 説明 |
|---|---|---|---|---|
page | int | いいえ | 1 | ページ番号。1 から開始 |
page_size | int | いいえ | 20 | 1 ページあたりの行数。200 を推奨(過大な値は切り詰められる) |
start_date | string | いいえ | — | 開始日 YYYY-MM-DD。timezone に従って解析される |
end_date | string | いいえ | — | 終了日(当日を含む) |
timezone | string | いいえ | UTC | 日付パラメータの解析に使うタイムゾーン。例:Asia/Shanghai。強く推奨。指定しないと境界がローカル時刻と一致しません |
api_key_id | int | いいえ | — | 特定の 1 つのキーの詳細のみを表示(現在のユーザーに属している必要あり) |
model | string | いいえ | — | モデル ID でフィルタ(例:claude-sonnet-5) |
stream | bool | いいえ | — | true でストリーミングのみ、false で非ストリーミングのみ |
billing_type | int | いいえ | — | 課金タイプ列挙(下記参照) |
sort_by | string | いいえ | created_at | ソートフィールド |
sort_order | string | いいえ | desc | asc または desc |
レスポンス構造
{
"code": 0,
"message": "success",
"data": {
"items": [ { /* UsageLog */ }, ... ],
"total": 30423,
"page": 1,
"page_size": 200,
"pages": 153
}
}ページネーションフィールドは data のトップレベルにあり、外側のエンベロープにはありません。詳細配列は data.items にあります。data 自体は配列ではありません。
単一レコードのフィールドマッピング
これらはコンソールの /usage ページの各列に厳密に対応します:
| コンソールの列 | JSON フィールド | 型 | 説明 |
|---|---|---|---|
| モデル | model | string | 実際に課金されたモデル ID |
| 推論の努力度 | reasoning_effort | string | null | low / medium / high / xhigh / max |
| インバウンドエンドポイント | inbound_endpoint | string | null | クライアントが呼び出したパス。例:/v1/messages |
| アップストリームエンドポイント | upstream_endpoint | string | null | 正規化されたアップストリームパス |
| リクエストタイプ | request_type | string | chat / stream / responses / messages など |
| ストリーミング | stream | bool | ストリーミングだったかどうか |
| 課金モード | billing_mode | string | token / per_request / image / subscription |
| 課金タイプ | billing_type | int | 課金タイプ列挙 |
| 倍率 | rate_multiplier | float | このリクエストに適用されたチャネル倍率 |
| 入力トークン | input_tokens | int | |
| 出力トークン | output_tokens | int | |
| キャッシュ作成 | cache_creation_tokens | int | すべてのキャッシュ書き込み |
| キャッシュ作成 5m | cache_creation_5m_tokens | int | Anthropic の一時的な 5 分間ティア |
| キャッシュ作成 1h | cache_creation_1h_tokens | int | Anthropic の 1 時間ティア |
| キャッシュ読み取り | cache_read_tokens | int | |
| 入力コスト | input_cost | float | USD |
| 出力コスト | output_cost | float | USD |
| キャッシュ作成コスト | cache_creation_cost | float | USD |
| キャッシュ読み取りコスト | cache_read_cost | float | USD |
| 定価合計 | total_cost | float | USD、倍率適用前 |
| 実際の課金額 | actual_cost | float | = total_cost × rate_multiplier。残高から実際に差し引かれる金額 |
| 初回トークンレイテンシ | first_token_ms | int | null | TTFT。ストリーミングで有効 |
| 総所要時間 | duration_ms | int | null | |
| 時刻 | created_at | ISO8601 | サーバー側の書き込み時刻 |
| リクエスト ID | request_id | string | トラブルシューティングとトレース用 |
| 画像生成 | image_count / image_size / image_output_tokens / image_output_cost | — | マルチモーダルリクエストのみ設定される |
| API Key | api_key_id + ネストされた api_key オブジェクト | int + obj | |
| グループ | group_id + ネストされた group オブジェクト | int + obj |
各レコードにはネストされた user / api_key / group オブジェクトが含まれます(1 行あたり約 +1KB)。api_key オブジェクトには完全なキーテキストが含まれるため、スクリプトのログ/スクリーンショット/CSV では必ずマスキングしてください。一括エクスポートで、ネストされたオブジェクトが不要な場合は、jq を使うか、クライアント側でフィールドマッピングして必要なフィールドだけを残してください。
課金タイプ列挙(billing_type)
| 値 | 意味 |
|---|---|
0 | トークンによる課金(大多数のリクエスト) |
1 | サブスクリプションのクォータから差し引き |
billing_mode フィールドは文字列版で、具体的な価格モデル(token / per_request / image / subscription など)を表します。より読みやすいため、分類には推奨されます。
4. トークンの更新
アクセストークンは 24 時間後に期限切れになります。更新方法は 2 通りあります:
refresh_token で更新する(スクリプト向けに推奨)
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refresh_token": "rt_756a220ffa..."
}新しい access_token を返します(通常は refresh_token もローテーションされます)。リフレッシュトークンは 30 日間有効です。
再ログインする
粗雑ですが単純で、使い捨てスクリプトに適しています。実行のたびに /auth/login を再度呼び出します。
5. コードサンプル
Bash + curl + jq
#!/usr/bin/env bash
set -e
EMAIL="${EMAIL:?set EMAIL env}"
PASSWORD="${PASSWORD:?set PASSWORD env}"
BASE="https://api.lmuai.com"
JWT=$(curl -s -X POST "$BASE/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}" \
| jq -r '.data.access_token')
[ -n "$JWT" ] && [ "$JWT" != "null" ] || { echo "login failed" >&2; exit 1; }
START="2026-06-01"; END="2026-06-30"; TZ="Asia/Shanghai"; PAGE_SIZE=200
# Fetch page 1 to get total
META=$(curl -s "$BASE/api/v1/usage?page=1&page_size=$PAGE_SIZE&start_date=$START&end_date=$END&timezone=$TZ" \
-H "Authorization: Bearer $JWT")
PAGES=$(echo "$META" | jq -r '.data.pages')
# CSV header
echo "created_at,model,request_type,input_tokens,output_tokens,cache_read_tokens,total_cost,actual_cost,duration_ms" > usage.csv
# Write page 1
echo "$META" | jq -r '.data.items[] | [.created_at, .model, .request_type, .input_tokens, .output_tokens, .cache_read_tokens, .total_cost, .actual_cost, .duration_ms] | @csv' >> usage.csv
# Fetch remaining pages
for ((p=2; p<=PAGES; p++)); do
curl -s "$BASE/api/v1/usage?page=$p&page_size=$PAGE_SIZE&start_date=$START&end_date=$END&timezone=$TZ" \
-H "Authorization: Bearer $JWT" \
| jq -r '.data.items[] | [.created_at, .model, .request_type, .input_tokens, .output_tokens, .cache_read_tokens, .total_cost, .actual_cost, .duration_ms] | @csv' >> usage.csv
done
echo "saved $(wc -l < usage.csv) lines to usage.csv"Python
import os, csv, requests
BASE = "https://api.lmuai.com"
EMAIL = os.environ["EMAIL"]
PASSWORD = os.environ["PASSWORD"]
def login() -> str:
r = requests.post(f"{BASE}/api/v1/auth/login",
json={"email": EMAIL, "password": PASSWORD},
timeout=15)
r.raise_for_status()
data = r.json()
if data["code"] != 0:
raise RuntimeError(data.get("message", "login failed"))
return data["data"]["access_token"]
def fetch_usage(jwt: str, **params):
"""Yield each row from paginated /usage endpoint."""
page = 1
while True:
r = requests.get(f"{BASE}/api/v1/usage",
headers={"Authorization": f"Bearer {jwt}"},
params={**params, "page": page, "page_size": 200},
timeout=30)
r.raise_for_status()
d = r.json()["data"]
for row in d.get("items", []):
yield row
if page >= d.get("pages", 1):
return
page += 1
if __name__ == "__main__":
jwt = login()
cols = ["created_at","model","request_type","input_tokens","output_tokens",
"cache_read_tokens","total_cost","actual_cost","duration_ms"]
with open("usage.csv", "w", newline="") as f:
w = csv.writer(f); w.writerow(cols)
for row in fetch_usage(jwt, start_date="2026-06-01", end_date="2026-06-30",
timezone="Asia/Shanghai"):
w.writerow([row.get(c) for c in cols])
print("done")Node.js
import fs from 'node:fs'
const BASE = 'https://api.lmuai.com'
const { EMAIL, PASSWORD } = process.env
async function login() {
const r = await fetch(`${BASE}/api/v1/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: EMAIL, password: PASSWORD }),
})
const j = await r.json()
if (j.code !== 0) throw new Error(j.message || 'login failed')
return j.data.access_token
}
async function* fetchUsage(jwt, params) {
for (let page = 1; ; page++) {
const q = new URLSearchParams({ ...params, page, page_size: '200' })
const r = await fetch(`${BASE}/api/v1/usage?${q}`, {
headers: { Authorization: `Bearer ${jwt}` },
})
const j = await r.json()
for (const row of j.data.items) yield row
if (page >= j.data.pages) return
}
}
const jwt = await login()
const cols = ['created_at','model','request_type','input_tokens','output_tokens',
'cache_read_tokens','total_cost','actual_cost','duration_ms']
const out = fs.createWriteStream('usage.csv')
out.write(cols.join(',') + '\n')
for await (const row of fetchUsage(jwt, {
start_date: '2026-06-01', end_date: '2026-06-30', timezone: 'Asia/Shanghai',
})) {
out.write(cols.map(c => JSON.stringify(row[c] ?? '')).join(',') + '\n')
}
console.log('done')6. 実践上の注意
- 大量のページ送りの間にディレイを入れる — N ページを連続でめくる場合、レート制限を回避するために
sleep(0.1~0.3s)を推奨します。 - 一度に長すぎる期間を取得しない — 数か月にまたがり数百万行にわたると遅くなります。月単位でスライスするほうが安定します。
page_sizeは 200 を推奨 — サーバーは過大な値を切り詰めます。- 帯域を節約する — ネストされた
user/api_key/groupオブジェクトは大きいため、詳細行だけが必要ならjqでクライアント側でフィルタしてください。 - よくあるエラー:
401JWT 期限切れ →refresh_tokenで更新するか再ログイン403権限のないアクセス(例:api_key_idで他人のキーをクエリ)→ そのキーが現在のユーザーに属していることを確認400パラメータ不正(例:start_dateの形式)→YYYY-MM-DD+timezoneが有効か確認
7. セキュリティに関する推奨事項(必読)
あなたのアカウントパスワード + JWT は、アカウントへのフルアクセスと同等です。 エクスポートをスクリプト化する前に、以下を確認してください:
| 項目 | 推奨事項 |
|---|---|
| 認証情報の管理 | password / access_token / refresh_token を git や CI ログに絶対にコミットしないこと。環境変数、シークレットマネージャー、または .env(.gitignore 付き)を使用する |
| アカウントのセキュリティ | TOTP 二要素認証の有効化を強く推奨します(アカウント設定で有効化)。この API はログイン時の TOTP 検証に対応しています |
| 定期的なローテーション | アカウントパスワードを定期的に変更し、refresh_token は期限切れ後すぐにローテーションする |
| 異常の監視 | アカウントの「最終ログイン時刻/IP」を監視し、見慣れないデバイスを見つけたらすぐにパスワードを変更する |
| フィールドのマスキング | レスポンス内のネストされた api_key.key(完全な sk-... テキスト)、user.email、refresh_token はすべて機密フィールドです。出力/ログ/CSV の前にマスキングしてください |
| 最小権限 | 分離できるなら、エクスポートスクリプト専用のサブアカウントを使用し(組織がマルチアカウント構成の場合)、メインアカウントの長期的な露出を避ける |
| エラーリトライ | ログイン失敗時に無限にリトライしないこと。リスク管理を容易にトリガーします。指数バックオフを推奨します |
8. フィールドクイックリファレンス
CSV の列マッピングに便利です:
| ラベル | フィールド | 単位 |
|---|---|---|
| モデル | model | — |
| 推論の努力度 | reasoning_effort | — |
| インバウンドエンドポイント | inbound_endpoint | path |
| アップストリームエンドポイント | upstream_endpoint | path |
| リクエストタイプ | request_type | enum |
| ストリーミング | stream | bool |
| 課金モード | billing_mode | enum |
| 課金タイプ | billing_type | int |
| 倍率 | rate_multiplier | float |
| 入力トークン | input_tokens | int |
| 出力トークン | output_tokens | int |
| キャッシュ読み取りトークン | cache_read_tokens | int |
| キャッシュ書き込みトークン | cache_creation_tokens | int |
| キャッシュ書き込み 5m | cache_creation_5m_tokens | int |
| キャッシュ書き込み 1h | cache_creation_1h_tokens | int |
| 入力コスト | input_cost | USD |
| 出力コスト | output_cost | USD |
| キャッシュ作成コスト | cache_creation_cost | USD |
| キャッシュ読み取りコスト | cache_read_cost | USD |
| 定価合計 | total_cost | USD |
| 実際の課金額 | actual_cost | USD |
| 初回トークン | first_token_ms | ms |
| 総所要時間 | duration_ms | ms |
| 時刻 | created_at | ISO8601 |
| リクエスト ID | request_id | string |
| グループ | group_id / group.name | int / string |
| API Key | api_key_id / api_key.name | int / string |
最終更新:
LMU AI の API キーを取得して、Claude や Codex をすぐに使う
登録は無料、プランは柔軟。1 つの API キーで Claude Code、Codex CLI、Cursor、VS Code 拡張、OpenCode、Cherry Studio などの AI ツールに接続できます。
登録する