Перейти к основному содержанию
Платформа отдаёт расход по каждому запросу прямо в ответе. Историю накапливать нужно самостоятельно: эндпоинта, отдающего историю потребления, на /api/v1 нет.

usage.cost в ответе

Каждый текстовый ответ содержит объект usage, а в нём — cost с суммой, списанной с кошелька в рублях:
total_cost — списание с кошелька. Именно эта сумма должна сойтись с вашим расчётом по cost_context и cost_completion из GET /api/v1/models.

Разбор токенов по трём текстовым эндпоинтам

/api/v1/chat/completions и /api/v1/responses

Одинаковый формат:

/api/v1/messages

Эндпоинт отвечает в формате Anthropic, и правила другие:
Соглашение Anthropic отличается от формата чат-эндпоинта: input_tokens не включает cache_read_input_tokens, а thinking_tokens (в output_tokens_details) входит в output_tokens. Складывать эти поля с базовыми нельзя — получите двойной счёт. И объекта cost на /api/v1/messages нет: расход считайте по формату чата либо по остатку баланса.
Единый разбор обоих форматов:
Python
cached_read_tokens и reasoning_tokens — подмножества, а не добавка. Считайте prompt = text + image + audio + cached и completion = text + reasoning + audio — только в таком порядке, и то, что выводите в отчёт, не разойдётся с чеком.

Баланс — снимок, а не история

cURL
GET /api/v1/balance отдаёт моментальный снимок остатка. Истории, разбивки по дням, по моделям и по пользователям на /api/v1 нет — такого эндпоинта не существует. Попытка вывести историю запросом к балансу невозможна по определению.
Разница между двумя соседними вызовами баланса — это расход всего аккаунта за это время, включая ваш собственный трафик, фоновые задачи и всё, что не прошло через вас. Считать по нему можно только в однопользовательском сценарии. Панель аналитики платформы — в веб-приложении на speshu.ai/profile. Это удобно посмотреть глазами, но для программной сверки нужен свой учёт.

Свой учёт

Единственный способ получить честную историю — писать строку по каждому запросу в свою базу сразу, в момент ответа.
Python
Ключевой момент — request_id: он связывает вашу строку с логами и с обращением в поддержку. Прокидывайте его через все слои, включая повторы, иначе при инциденте вы не найдёте, какой именно вызов стоил денег.
Пишите строку даже при ошибке. Отказ до обращения к модели ничего не списывает, но неудачный запрос с 500 на середине генерации — вполне может. Пустое место в истории хуже нулевой суммы.

Многопользовательский продукт

user в теле запроса принимается, но не используется для атрибуции: запрос всегда относится к владельцу ключа. Списать расход с пользователя вашего приложения по полям API нельзя.
Python
Сопоставление строится в вашем коде: вы знаете, в каком обработчике был выполнен вызов, и записываете туда своего пользователя. Всё, что вы пишете в metadata или user тела запроса, обратно в вашу базу не возвращается.
Практический приём — отдельный API-ключ на каждого пользователя вашего приложения. Тогда атрибуция делается сама: у каждого ключа свой кошелёк и своя история в панели. Плата за управление ключами — при большом числе пользователей это становится неудобно; решение за вами.

Пороги и алерты

Пороги считайте по своей таблице, а не по балансу: баланс — общее состояние кошелька, а бюджет — ваше понятие.
Python
Что стоит контролировать:
402 insufficient_quota приходит до обращения к модели, деньги за него не списываются. Это отказ, а не расход: платить за него не нужно, а вот пропущенный алерт об исчерпании баланса обойдётся дороже.

Что дальше

Биллинг

Как считается стоимость запроса

Баланс

Формат ответа и коды

Кэширование

Как уменьшить входную часть расхода

Токены рассуждений

Почему растёт выходная часть