Мониторинг расхода в реальном времени по заголовкам ответа
Не нужно ждать отчёта за сутки, чтобы узнать, сколько стоил запрос — цена и остаток баланса приходят в заголовках каждого обычного (не потокового) ответа. Как это использовать.
4 мин · · Обновлено · API · экономия
Обычно расход на API узнаёшь постфактум: смотришь дашборд, видишь сумму за сутки, разбираешься, какой из десяти эндпоинтов её накрутил. Здесь можно иначе — цена конкретного запроса и остаток баланса приходят прямо в заголовках ответа, без похода в отдельный отчёт.
Два заголовка, которые решают половину задачи мониторинга
Каждый обычный (не потоковый) ответ несёт:
X-Zukko-Cost-Micros— стоимость именно этого запроса в микродолларах (1,000,000 = $1).X-Fetch-Balance-Cents— остаток баланса после списания. Несмотря на название, значение тоже в микродолларах (1,000,000 = $1); точный баланс в центах —GET /v1/balance, полеbalance_cents.
У потоковых ответов (stream: true) этих заголовков нет — для них расход смотри в кабинете, /v1/usage или /v1/balance.
curl -si https://api.zukko.pro/v1/chat/completions \
-H "Authorization: Bearer fetch_твой_ключ" \
-H "Content-Type: application/json" \
-d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":"тест"}]}' \
| grep -i "x-zukko-cost\|x-fetch-balance"Ничего не нужно вычислять из токенов и прайс-листа отдельно — цена уже посчитана на стороне шлюза с учётом конкретной модели.
Логировать заголовки, а не ждать выгрузки
Простая обёртка на Python, которая пишет стоимость каждого вызова в свою систему метрик вместо похода в кабинет раз в день:
import requests
def call_model(payload, api_key):
resp = requests.post(
"https://api.zukko.pro/v1/chat/completions",
headers={"Authorization": f"Bearer {api_key}"},
json=payload,
)
cost_micros = int(resp.headers.get("X-Zukko-Cost-Micros", 0))
# несмотря на название, заголовок в микродолларах (1_000_000 = $1)
balance_micros = int(resp.headers.get("X-Fetch-Balance-Cents", 0))
metrics.gauge("zukko.balance_micros", balance_micros)
metrics.increment("zukko.cost_micros", cost_micros)
if balance_micros < 5_000_000: # меньше $5 — сигнал тревоги
alert("Баланс zukko.pro ниже $5")
return resp.json()На JS то же самое:
const resp = await fetch("https://api.zukko.pro/v1/chat/completions", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
const costMicros = Number(resp.headers.get("x-zukko-cost-micros"));
const balanceMicros = Number(resp.headers.get("x-fetch-balance-cents")); // микродолларыРазница с постфактум-отчётом: алерт срабатывает в момент запроса, который пробил порог, а не на следующий день при разборе логов.
Привязка стоимости к конкретному запросу, а не к среднему по больнице
Если сервис делает вызовы к разным моделям в рамках одного пользовательского действия — например, сначала классифицирует запрос лёгкой моделью, потом обрабатывает флагманом — заголовок с каждого отдельного HTTP-ответа даёт точную стоимость каждого шага. Складывая X-Zukko-Cost-Micros по всем вызовам одной пользовательской сессии, получаешь реальную unit-экономику фичи, а не грубую оценку "в среднем по всем моделям".
Кэш — это бесплатные повторы, и это тоже видно в заголовках
Если запрос идёт с заголовком X-Zukko-Cache: true (temperature: 0 тоже включает кэш, но только у моделей, которые его принимают, — модели Claude могут отклонить temperature, отличный от 1), одинаковые запросы одного и того же пользователя кэшируются (для чата — на срок до 7 суток). Повторный идентичный запрос возвращается мгновенно и не тарифицируется, а в ответе это отмечено заголовком X-Zukko-Cache: hit. Кэш срабатывает только при полном совпадении тела запроса, и такие попадания не пишутся в /v1/usage. Стоит логировать и его — доля кэш-хитов прямо показывает, сколько трафика можно было не оплачивать, если включить кэш там, где сейчас его нет:
curl -si https://api.zukko.pro/v1/chat/completions \
-H "Authorization: Bearer fetch_твой_ключ" \
-H "X-Zukko-Cache: true" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.6-sol","messages":[{"role":"user","content":"тест"}]}' \
| grep -i "x-zukko-cache"/v1/usage — для сверки, не для реального времени
Заголовки дают моментальный срез, а история списаний с курсорной пагинацией нужна для сверки за период. Она общая на весь аккаунт (все ключи вместе, фильтра по ключу нет); в каждой записи — created_at, model, input_tokens, output_tokens, total_tokens и cost_cents (дробные центы), для следующей страницы — next_cursor:
curl https://api.zukko.pro/v1/usage \
-H "Authorization: Bearer fetch_твой_ключ"Разумная схема: заголовки пишутся в метрики на каждый вызов и триггерят алерты сразу, а /v1/usage раз в день сверяет сумму заголовков с официальной историей — учитывай, что потоковые запросы в заголовках не видны и есть только в /v1/usage; если без них числа расходятся, значит где-то логирование заголовков само отваливается, и это стоит найти раньше, чем разойдётся счёт.
Баланс аккаунта отдельно от баланса конкретного ключа
X-Fetch-Balance-Cents показывает баланс всего аккаунта, а не лимит конкретного ключа — если на ключе настроен дневной или месячный лимит расхода, он тарифицируется отдельно и виден через 429 с кодом key_daily_limit_reached или key_monthly_limit_reached, когда исчерпан. Для мониторинга по ключу с лимитом стоит отдельно считать сумму X-Zukko-Cost-Micros за день на своей стороне и сравнивать с выставленным лимитом, чтобы видеть приближение к порогу заранее, а не только в момент отказа.
Быстрая проверка, что всё подключено
Общий баланс без разбора по запросам всегда можно дёрнуть напрямую:
curl https://api.zukko.pro/v1/balance \
-H "Authorization: Bearer fetch_твой_ключ"Если цифра из /v1/balance расходится с тем, что накопилось в логах по заголовкам — значит, в обёртке вокруг HTTP-клиента заголовки не читаются или теряются при ретраях, и стоит проверить именно этот участок кода, а не сам биллинг.
Оценка стоимости до отправки, а не после
Заголовки хорошо показывают, сколько стоил уже отправленный запрос, но иногда нужно узнать цену заранее — например, перед батчем из тысячи промптов, который дешевле остановить до отправки, чем мониторить в процессе. Для этого есть отдельный бесплатный эндпоинт, который считает токены без выполнения запроса:
curl https://api.zukko.pro/v1/messages/count_tokens \
-H "Authorization: Bearer fetch_твой_ключ" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"claude-opus-5-5","messages":[{"role":"user","content":"..."}]}'Зная число токенов и текущую цену модели из /v1/models/info, можно прикинуть стоимость всего батча до того, как он ушёл, и сравнить с лимитом, выставленным на ключе — вместо того чтобы узнавать реальную сумму постфактум из заголовков или /v1/usage.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- Агенты opencode: как настроить роли, модели и инструментыСвой агент в opencode — это роль, модель и список разрешений. Показываем конфиг и пример, где рутину делает дешёвая модель, а код правит сильная.
- Plan mode в Claude Code: сначала план, потом правки в кодеВ plan mode Claude Code читает код и предлагает план, но ничего не правит, пока вы не согласитесь. Как включить, использовать и во сколько это обходится.
- Купить токены нейросети: как устроен баланс в долларах и что на него взять«Токены» в шлюзе — это не пакет, а баланс в долларах. Разбираем, что с него списывается, и считаем, на сколько запросов хватит $5.
- Оплата нейросетей без комиссии: бывает ли так и как посчитать переплатуКомиссия при пополнении есть почти всегда. Показываем, из чего она складывается, считаем её для СБП и карты и даём формулу «сколько рублей нужно на N долларов».