HiAPI
Блог

Руководство

Почему HiAPI всё равно списывает средства при неудачном запросе?

Oct 8, 2026
Почему HiAPI всё равно списывает средства при неудачном запросе?

Симптомы проблемы

Вы отправляете задачу генерации через POST на https://api.hiapi.ai/v1/tasks, затем опрашиваете её через GET /v1/tasks/:id и получаете "status": "fail" вместе с объектом error, например {"code": "TASK_FAILED", "message": "task failed"}. HTTP-код самого этого запроса опроса нормальный — 200: HiAPI упаковывает информацию об ошибке в тело JSON, а не в код состояния. Поскольку задача действительно прошла через queued → handling и только потом завершилась неудачей, легко предположить, что эта попытка, как и обычный вызов, была списана. На самом деле переход задачи в терминальное состояние fail не означает списания — но если вы проверили баланс до того, как вернулся возврат, та резервация, сделанная при создании, действительно может создать впечатление, что деньги списаны.

Частые причины

  1. Путаница между «резервацией» и «списанием». HiAPI резервирует предполагаемую стоимость задачи в момент её создания, ещё до того, как она реально начнёт выполняться. Эта резервация сразу отражается в вашем балансе — но это ещё не списание.
  2. Проверка баланса во время выполнения задачи. Между queued/handling и терминальным состоянием эта резервация «висит» — так и задумано. Только терминальное состояние (success или fail) её закрывает.
  3. Смешение «нижестоящий сервис реально отработал, но с ошибкой» и «отклонено на этапе создания». Задача, дошедшая до status: "fail" (например, error.code: "TASK_FAILED"), была реально создана, реально выполнялась, и нижестоящий сервис вернул ошибку — документация HiAPI прямо указывает, что после перехода задачи в это терминальное состояние зарезервированная сумма автоматически возвращается в полном объёме. А запрос, который так и не получил taskId — например, синхронно возвращённый 402 INSUFFICIENT_QUOTA — был отклонён ещё до появления задачи, и резервировать было нечего. Снаружи оба выглядят как «неудача», но только первый действительно затронул механизм резервации.
  4. Неправильное использование Idempotency-Key. Повтор с тем же key и тем же телом запроса просто вернёт исходный taskId, не создаст задачу и не спишет второй раз. Но повтор с тем же key и изменённым телом запроса сразу вернёт на этапе создания 422 IDEMPOTENCY_KEY_MISMATCH; повтор с тем же key, пока первый вызов ещё не обработан, вернёт 409 IDEMPOTENCY_KEY_PROCESSING. Ни один из этих путей не создаёт оплачиваемую задачу.

Шаги исправления

  1. Опрашивайте GET /v1/tasks/:id и смотрите прямо на data.status — не угадывайте результат списания по одному скриншоту баланса. queued, handling, archiving — все нетерминальные; только success и fail терминальны.
  2. Если data.status равен "fail", это результат, подлежащий возврату. Посмотрите data.error.code (например, TASK_FAILED), чтобы понять причину, затем проверьте баланс снова — возврат придёт автоматически после перехода задачи в это терминальное состояние.
  3. Если сам вызов POST /v1/tasks вернул код не 2xx (400/402/409/415/422) и в теле нет taskId, то возвращать нечего — задача не была создана и деньги не списывались. Конкретный случай недостатка средств проявляется как error_code: "INSUFFICIENT_QUOTA" в ответе 402.
  4. Проверьте в панели биллинга HiAPI пару транзакций «резервация — возврат», а не просто число баланса в какой-то момент времени.
  5. При повторной попытке неудачной задачи используйте новый Idempotency-Key для этой действительно новой попытки. Не повторяйте с изменённым телом запроса под старым key (это вызовет 422) и не отправляйте повторно с тем же key, пока первый запрос ещё обрабатывается (это вызовет 409).
  6. Если вы уверены, что задача достигла терминального состояния fail, но зарезервированная сумма спустя некоторое время так и не вернулась, это выходит за рамки механизма автоматического возврата — обратитесь в поддержку напрямую, не предполагайте, что оно восстановится само.

Минимальный пример проверки

curl -s -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "model": "gpt-image-2/text-to-image",
    "input": { "prompt": "a minimalist desk setup, studio lighting" }
  }'

Здесь в поле model указан суффикс маршрута /text-to-image. На момент написания этой статьи в индексе моделей HiAPI для группы gpt-image-2 есть только записи с суффиксом маршрута (/text-to-image, /image-to-image), записей с голым id нет. Нужен ли суффикс и какой именно — обязательно ориентируйтесь на записи с availability: "online" в этом актуальном индексе моделей, не копируйте написание из других моделей или старой документации.

Получив taskId в ответе, опрашивайте:

curl -s https://api.hiapi.ai/v1/tasks/$TASK_ID \
  -H "Authorization: Bearer $HIAPI_API_KEY"

Неудачная задача с возвратом выглядит так:

{
  "code": 200,
  "message": "success",
  "data": {
    "taskId": "tk-hiapi-...",
    "model": "gpt-image-2/text-to-image",
    "status": "fail",
    "created": 1777282033,
    "completed": 1777282099,
    "error": { "code": "TASK_FAILED", "message": "task failed" }
  }
}

Связанные внутренние ссылки

FAQ

Спишет ли HiAPI деньги, если задача генерации изображения или видео завершилась неудачей? Нет. Как только задача переходит в терминальное состояние fail, зарезервированная при создании сумма автоматически возвращается в полном объёме.

После отправки задачи баланс сразу уменьшился, а задача потом завершилась неудачей — почему баланс не восстановился? Это уменьшение — резервация при создании, а не списание. Она закрывается автоматически после перехода задачи в терминальное состояние — при fail возвращается, при success действительно расходуется.

В чём разница между ошибкой 402 и неудачей задачи? 402 INSUFFICIENT_QUOTA означает, что задача вообще не была создана, поэтому нечего было резервировать и нечего возвращать. А задача, получившая taskId и затем перешедшая в status "fail", была реально создана, реально выполнялась, а затем нижестоящий сервис вернул ошибку; HiAPI автоматически вернёт эту резервацию.

Спишутся ли деньги дважды при повторе с тем же Idempotency-Key? Нет. Повтор с тем же key и тем же телом запроса просто вернёт исходный taskId и не создаст новую задачу. Если под тем же key изменить тело запроса, сразу вернётся 422 IDEMPOTENCY_KEY_MISMATCH, и дублирующая задача тоже не создастся.

Где увидеть записи о резервациях и возвратах? В счетах и истории транзакций в панели биллинга HiAPI.

Похожие статьи

Все статьи →

Начните работать с постоянными артефактами ИИ

Получите API-ключ и вызывайте модели изображений, видео и аудио через один API на основе tasks.

Читать документацию API