Кредиты и оплата
1 кредит = 1 цент. Как считается цена картинок, видео и чата, когда списываются кредиты, эндпоинт остатка GET /v1/credits и стоимость каждого запроса.
Курс
1 кредит = 1 цент США ($0.01). Все цены в API и каталоге — в кредитах. Баланс пополняется и отслеживается в дашборде.
Учёт ведётся с точностью до микро-доллара (1 кредит = 10 000 µUSD): дешёвый чат-вызов
стоит доли цента, и целый кредит был бы слишком грубой единицей. Все денежные поля API —
целые числа в микро-USD, без округления: price, usage.cost, баланс в /v1/credits,
суммы в вебхуках. Перевод в кредиты для показа человеку — деление на micro_usd_per_credit
(= 10 000) из ответа /v1/credits; как округлять при показе, решает твой интерфейс. Дашборд
СОЮЗа, например, округляет баланс до сотых кредита, а цены запросов в истории показывает точно.
Как считается цена
Правило одно для всего: цена = фактическая себестоимость генерации × единая наценка
платформы. Отдельных прейскурантов «по ценности» нет: если параметр ничего не стоит
провайдеру (например, звук у Seedance или разрешение у картинок с плоской ставкой), он ничего
не стоит и тебе. На первом внутреннем профиле тарифы передаются продукту вместе с
сертифицированным allow-list; /v1/models до общего gate выключен.
| Модальность | Из чего складывается себестоимость |
|---|---|
| Картинки | плоская ставка за вызов — разрешение и качество цену не меняют |
| Видео | посекундный тариф × длительность; тариф зависит от ступени качества (режим у Kling, разрешение у Seedance) и — только там, где звук платный, — от звука |
| Чат | ставка за 1М входных + за 1М выходных токенов, списание по фактическому usage — с точностью до микро-доллара, дешёвый вызов стоит доли цента |
До завершения работы price — это верхняя оценка: бронь по самому дорогому маршруту,
который мог бы выполнить запрос. Итоговое списание после успеха никогда не превышает эту
оценку, а когда апстрим сообщает фактический расход или работу выполнил более дешёвый маршрут —
оказывается ниже; разница возвращается автоматически. Неудачные попытки внутри водопада не
тарифицируются — их покрывает наценка.
Остаток по API
GET /v1/credits — программная проверка баланса (для мониторинга и алертов «кредиты кончаются»):
curl https://api.souz.ai/v1/credits -H "Authorization: Bearer sk-souz-..."
{
"object": "credits",
"balance": 123456700,
"reserved": 840500,
"overdraft_limit": 0,
"unit": "micro_usd",
"micro_usd_per_credit": 10000,
"currency": "credits",
"credit_value_usd": 0.01,
"rate_limit": { "requests_per_minute": 1000 }
}
Суммы — целые микро-USD (здесь баланс 123 456 700 µUSD = 12 345.67 кредита). Для показа
человеку раздели на micro_usd_per_credit и округляй как удобно твоему интерфейсу.
balance — доступно к трате, reserved — временно удержано выполняющимися джобами. При успехе
из reserved уходит фактическая стоимость, а неиспользованный остаток (если он есть)
возвращается в balance; при сбое деньги не списываются — резерв возвращается либо
не создавался. Бонусом — действующий лимит запросов твоего ключа.
Когда списываются кредиты
- Резерв. При создании запроса ожидаемая стоимость уходит из
balanceвreserved. - Успех. Из резерва списывается итоговая цена успешной генерации — себестоимость
выполнившего маршрута (по фактическому расходу апстрима, где он сообщается) × наценка, — а
неиспользованный остаток возвращается в
balanceтем же коммитом. Списание никогда не превышает показанную при создании оценку.allow_degradationработает по общему правилу: деградированный outcome дешевле, потому что дешевле его себестоимость (сейчас опубликован только Nano Banana Proreferences 9–14 → первые 8). Для чата резерв — верхняя оценка, а разница по фактическим токенам возвращается. - Сбой, который видно в джобе. Если джоба завершилась
failed, деньги не списываются: созданный резерв возвращается тем же коммитом, что и этот статус, а при немедленном отказе (например, capability или недостаток средств) резерв вообще не создаётся. За такие генерации ты не платишь.
Чего мы не обещаем (честно, чтобы не было сюрпризов в сверке):
- Оборванный чат-стрим. Если ответ уже начал приходить и потом упал (ошибка апстрима или разрыв соединения), запрос закрывается по фактически отданному объёму — по учтённым или оценённым токенам, а не полным возвратом. Ты платишь за то, что успел получить.
- Падение нашего процесса. Резерв и запись джобы, как и списание и её финальный статус, идут одной транзакцией: после сбоя либо произошло и то и другое, либо ничего. Если провайдер ещё не вызывался, сверка возвращает резерв ровно один раз. Если durable-попытка уже была начата, деньги двигаются только после доказательства от апстрима: результат → списание, доказанное отсутствие работы → возврат; одного возраста джобы недостаточно. Чего мы не обещаем: мгновенности и автоматического исхода, когда доказательство получить нельзя. Для новой async-джобы принятый результат проходит durable artifact protocol: объект проверяется по контрольной сумме, а его манифест, списание и terminal status коммитятся атомарно. После рестарта воркер продолжает тот же provider task, а не создаёт новую платную работу. Старое или противоречивое состояние «списание есть, доставляемого результата нет» всё ещё замораживается для оператора: выдумывать обратную проводку или успех без файла система не будет.
- Падение во время вызова провайдера. Перед вызовом мы durable записываем намерение отправки. После рестарта такая попытка не отправляется повторно: она переходит в разбор как «могла уйти». Для async-варианта допускается только провайдер с доказанным повторным получением того же результата по durable task id. Sync-провайдер, который возвращает только тело ответа и не даёт recovery-механизма, отсекается до резерва.
- Небезопасный результат провайдера. Результат проходит лимиты размера, SSRF-защиту и
проверку формата/полного декодирования до сохранения. Если уже оплаченные байты не проходят эту
политику, система не делает fallback и не возвращает резерв по одному факту ошибки: джоба
остаётся
in_progress, а тот же durable task сверяется повторно. Это исключает вторую платную генерацию и не выдаёт клиенту потенциально опасный файл. Видео первого ProductionGo-среза отклоняется ещё до резерва и вызова провайдера, пока bounded video validator не сертифицирован. - Неподтверждённая попытка у провайдера. Если связь оборвалась уже после отправки запроса
(таймаут, разрыв,
408или любой5xxот шлюза), мы не знаем, выполнил провайдер работу или нет — и в этот момент не делаем ничего необратимого: другого провайдера не зовём и резерв не возвращаем сразу. Запрос ждёт сверки: если апстрим подтвердит результат, джоба станетcompletedс обычным списанием; если апстрим докажет, что запрос не был принят или закончился без результата, джоба станетfailed, а резерв вернётся ровно один раз. Если механизма проверки нет, апстрим всё ещё выполняет работу или lookup падает, джоба остаётсяin_progress, а резерв удерживается: время само по себе не доказывает неуспех. Для чата это видно как502 model_unavailableпри удержанном резерве. Так мы не платим дважды за одну и ту же работу. - Повтор запроса после ошибки
500в чате. Чат не поддерживает ключ идемпотентности: повтор — это новая генерация и новая оплата. Решай осознанно, автоматический ретрай тут не наш контракт. Это тем более верно после502с неподтверждённой попыткой: сначала посмотри историю.
Если баланса не хватает:
- синхронный чат → сразу
402 insufficient_credits; - картинки и видео →
400и объект джобы соstatus: "failed",error.code: "insufficient_credits"; в полеpriceпри этом указана посчитанная цена запроса. Резерв не создаётся, деньги не двигаются.
Стоимость каждого запроса
- Картинки и видео: поле
priceв объекте джобы (и в ответе создания, и при опросеGET /v1/jobs/{id}). - Чат без стриминга: поле
usage.costв ответе. В стриме оно приходит в usage-чанке, если апстрим этот чанк прислал; при обрыве/отсутствующем usage публичногоcostможет не быть, хотя расчёт всё равно завершается по доступным данным.
{ "usage": { "prompt_tokens": 16, "completion_tokens": 120, "cost": 224 } }
История расходов
Полная история запросов и график расходов по дням и моделям — в дашборде, раздел «История».