> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kvantora.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Баланс и стоимость

> Бюджет в рублях, показ расходов и подтверждённое списание.

Бюджет и расходы показывайте в рублях с двумя знаками после запятой, например **0,99 ₽**. Остальные знаки отбрасывайте. Это правило отображения; точная сумма запроса и списания не меняется.

## Суммы в API

Денежные поля API содержат целые числа: **1 ₽ = 1 000 000 единиц API**. Например, значение API `999750` отображается как **0,99 ₽**; для расчётов сохраняйте исходное целое число. `GET /v1/balance` требует `balance:read` и возвращает `availableMicrorub`, `reservedMicrorub`, `currency=RUB` и `unit=microrub`. Имена полей и значение `unit` не меняются.

Для положительных сумм этот пример принимает бюджет в рублях и показывает ответ API без потери исходного значения:

```javascript theme={null}
function rublesToApiUnits(rubles) {
  if (!/^\d+(?:\.\d{1,2})?$/.test(rubles)) {
    throw new Error('Введите рубли строкой с точкой и не более двух знаков');
  }
  const [whole, fraction = ''] = rubles.split('.');
  const amount = BigInt(whole) * 1_000_000n
    + BigInt(fraction.padEnd(2, '0')) * 10_000n;
  if (amount > BigInt(Number.MAX_SAFE_INTEGER)) {
    throw new Error('Сумма превышает допустимый предел API');
  }
  return Number(amount);
}

function formatRubles(apiAmount) {
  if (!Number.isSafeInteger(apiAmount) || apiAmount < 0) {
    throw new Error('Ожидается неотрицательная целая сумма API');
  }
  const kopecks = BigInt(apiAmount) / 10_000n;
  return String(kopecks / 100n) + ','
    + String(kopecks % 100n).padStart(2, '0') + ' ₽';
}

const budgetRub = '10.00';
const maxCostApi = rublesToApiUnits(budgetRub);
console.log(formatRubles(maxCostApi)); // 10,00 ₽
console.log(formatRubles(999750)); // 0,99 ₽
```

Для показа используйте `formatRubles`; для отправки — исходное целое число. Не рассчитывайте платёж из уже сокращённой строки. Код выше подходит для шага с JavaScript в Kvantora Flow.

## Резерв и списание

Перед платным запросом сервис резервирует верхнюю оценку. После подтверждённого результата списывает фактическую сумму один раз и освобождает остаток. Если исход неизвестен, резерв сохраняется до сверки.

Медиа сейчас используют фиксированную цену за запрос. `POST /v1/quotes` возвращает `estimated_cost_microrub`, `expires_at` и `reservation_created=false`. Можно передать точную оценку без изменений в `max_cost_microrub` либо задать собственный предел через `rublesToApiUnits(budgetRub)`. Если текущая цена выше предела, запрос не отправится.

## Оценка запроса медиа

В оценку передайте параметры будущей генерации и нужную `operation`. Этот запрос не создаёт задание и не резервирует деньги.

```javascript theme={null}
const parameters = {
  model: process.env.KVANTORA_MODEL_ID,
  prompt: 'Лесное озеро на рассвете',
  n: 1,
};
const response = await fetch(process.env.KVANTORA_BASE_URL + '/v1/quotes', {
  method: 'POST',
  redirect: 'error',
  headers: {
    Authorization: 'Bearer ' + process.env.KVANTORA_API_KEY,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ ...parameters, operation: 'image_generation' }),
});
if (!response.ok) throw new Error('Оценка не получена: HTTP ' + response.status);
const quote = await response.json();
console.log(formatRubles(quote.estimated_cost_microrub));
```

Функция `formatRubles` определена выше. Проверяйте `expires_at` перед отправкой. Для генерации передайте `parameters` и точное `max_cost_microrub`, но не добавляйте `operation`: её задаёт endpoint. Оценка не является гарантией доступности модели к моменту отправки.

## История расходов

`GET /v1/usage?days=30` требует `usage:read`. `requests` считает принятые запросы проекта; `spent` суммирует подтверждённые списания по времени их завершения. Резервы не входят в `spent`. Период начинается по календарным дням в `billing_timezone` организации и заканчивается `as_of`.
