Экспорт детализации использования
Руководство по экспорту использования LMU AI: войдите, чтобы получить JWT, затем вызовите /api/v1/usage с пагинацией, диапазоном дат и фильтрацией по модели, с примерами на трёх языках.
Войдите с помощью аккаунта и пароля, чтобы получить JWT, затем используйте этот JWT для вызова /api/v1/usage и получения полной таблицы детализации использования токенов, идентичной странице /usage в консоли.
Идеально для долго работающих скриптов, автоматизирующих экспорт, сверку и загрузку в корпоративный BI — не нужно каждый раз вручную выгружать CSV.
Почему нельзя получить это напрямую с помощью ключа API sk-...? Ключ предназначен только для бизнес-вызовов шлюза (/v1/messages и т. д.) и не открывает доступ к запросам детализации на уровне аккаунта — это намеренное решение по безопасности: если ключ утечёт, вы не захотите, чтобы весь ваш счёт стал доступен. Данные на уровне аккаунта должны использовать аутентификацию аккаунта (JWT).
1. Обзор API
| Параметр | Значение |
|---|---|
| Base URL | https://api.lmuai.com |
| Аутентификация | Authorization: Bearer <access_token> (JWT, полученный при входе в аккаунт) |
| Срок действия access token | 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 | Строк на страницу, рекомендуется 200 (слишком большие значения усекаются) |
start_date | string | Нет | — | Начальная дата YYYY-MM-DD, разбирается согласно timezone |
end_date | string | Нет | — | Конечная дата (включительно) |
timezone | string | Нет | UTC | Часовой пояс для разбора параметров даты, например Asia/Shanghai; настоятельно рекомендуется, иначе границы не совпадут с вашим локальным временем |
api_key_id | int | Нет | — | Просмотр детализации только одного ключа (должен принадлежать текущему пользователю) |
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 | Все записи в кэш |
| Создание кэша 5м | cache_creation_5m_tokens | int | Эфемерный уровень Anthropic на 5 минут |
| Создание кэша 1ч | 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КБ на строку). Объект api_key содержит полный текст ключа — обязательно скрывайте его в логах / скриншотах / CSV скриптов; для массового экспорта, если вложенные объекты вам не нужны, используйте jq или сопоставление полей на клиенте, чтобы оставить только нужные поля.
Перечисление типа биллинга (billing_type)
| Значение | Смысл |
|---|---|
0 | Оплата по токенам (подавляющее большинство запросов) |
1 | Списание из квоты подписки |
Поле billing_mode — строковая версия, описывающая конкретную модель ценообразования (token / per_request / image / subscription и т. д.); она более читаема и рекомендуется для категоризации.
4. Обновление токена
Access token истекает через 24 часа. Обновить его можно двумя способами:
Обновление с помощью refresh_token (рекомендуется для скриптов)
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refresh_token": "rt_756a220ffa..."
}Возвращает новый access_token (и обычно также ротирует refresh_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 |
| Запись кэша 5м | cache_creation_5m_tokens | int |
| Запись кэша 1ч | 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 |
Последнее обновление:
Получите API-ключ LMU AI и начните использовать Claude, Codex и другие инструменты
Бесплатная регистрация и гибкие тарифы. Один API-ключ для Claude Code, Codex CLI, Cursor, расширения VS Code, OpenCode, Cherry Studio и других ИИ-инструментов.
ЗарегистрироватьсяGemini Batch Image API
Асинхронный пакетный API изображений LMU AI: отправляйте множество задач генерации изображений Gemini за раз, опрашивайте статус и детали, скачивайте изображения или ZIP, с идемпотентностью и оценкой стоимости.
Enterprise
Корпоративные тарифы LMU AI для API Claude / GPT / Gemini: 6 SKU (Enterprise Standard + Flagship) на платформах Anthropic и OpenAI, с контрактами, счетами и поддержкой.