HiAPI
Блог

Руководство

URL результатов задач HiAPI истекает (expireAt): скачайте и перенесите результаты до истечения срока

В финальном состоянии output[].url содержит expireAt, после истечения — 404. Как определить, как вовремя скачать, как восстановиться после истечения.

Oct 22, 2026
URL результатов задач HiAPI истекает (expireAt): скачайте и перенесите результаты до истечения срока

Вы создаёте изображение или видео через POST /v1/tasks, после завершения задачи получаете из data.output[0].url ссылку на temp.hiapi.ai — она открывается сразу, но через несколько дней превращается в HTML-страницу «Not Found»:

HTTP/2 404
content-type: text/html

Возвращаются не байты изображения/видео, а страница 404 от Cloudflare. Причина одна: URL результатов задачи — это временная ссылка с ограниченным сроком действия, как только наступает expireAt (Unix-временная метка) из финального состояния, объект на temp.hiapi.ai удаляется, и горячая ссылка перестаёт работать.

Сначала разберём поля в финальном состоянии

При успешном опросе финального состояния задачи (GET /v1/tasks/{taskId}) ключевые поля выглядят так:

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-xxxxxxxx",
    "status": "success",
    "storage": "temp",
    "created": 1791828181,
    "completed": 1791828201,
    "output": [
      {
        "artifactId": "...",
        "type": "image",
        "url": "https://temp.hiapi.ai/....png",
        "expireAt": 1792432981
      }
    ]
  },
  "message": "success"
}
  • data.status == "success" — это финальное успешное состояние (при ошибке — "fail", в очереди/в обработке — queued / handling / archiving).
  • data.output — это массив, каждый элемент содержит свои url и expireAt.
  • expireAt — это целочисленная Unix-метка времени (не ISO-строка). Для определения истечения смотрите только на неё: now >= expireAt — истёк.
  • Значение data.storage — "temp": это само по себе подсказка, что хранилище временное и не предназначено для долгосрочных ссылок.

Как долго действует ссылка? В одном измеренном образце expireAt - completed = 604800 секунд (ровно 7 дней). Но не вписывайте «7 дней» жёстко в код — ориентируйтесь на expireAt каждого вывода, для разных моделей/стратегий хранения он может отличаться.

Типичные причины (по убыванию вероятности)

  1. Сохранение горячей ссылки в базу данных для долгосрочного использования: при записи в базу сохраняется временный URL temp.hiapi.ai/..., и после expireAt всё массово отдаёт 404. Это самая частая ошибка.
  2. Скачивание не сразу после получения финального состояния: байты запрашиваются спустя долгое время (дольше TTL) после завершения задачи.
  3. Ожидание, что повторный опрос «обновит» ссылку: повторный GET по тому же taskId возвращает ту же самую url и тот же expireAt — метаданные сохраняются, но сам объект после истечения не восстанавливается, повторный GET не даст новую ссылку.
  4. Ошибочное восприятие 404 как ошибки задачи: задача давно success, просто актив-вывод истёк — это две разные вещи.

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

  1. Как только наступило финальное состояние — сразу скачивайте байты. После опроса до data.status == "success" немедленно отправляйте GET по каждому output[].url и забирайте двоичные данные, не ставьте в очередь, не откладывайте.
  2. Перенесите в собственное объектное хранилище (R2 / S3 / локальный диск), замените на свой постоянный URL.
  3. В базе данных храните только свой постоянный URL, никогда не сохраняйте горячую ссылку temp.hiapi.ai.
  4. Перед скачиванием проверяйте, что срок не истёк: скачивайте, если now < expireAt; если уже истёк — сразу переходите к логике перезапуска.
  5. После истечения остаётся только перезапустить задачу. Обмена «taskId на новую ссылку» не существует — повторный GET по тому же taskId вернёт ту же недействительную url. Чтобы снова получить скачиваемый результат, нужно заново отправить задачу (с повторной оплатой).
  6. Для пакетных задач контролируйте порядок скачивания: у той задачи в пакете, что завершилась первой, expireAt тоже наступает раньше всех. Скачивайте сразу по мере завершения, не ждите завершения всего пакета для единовременного скачивания, иначе у завершившихся раньше срок может уже подходить к концу.

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

Убедитесь, что ваш ключ работает, интерфейс задач возвращает результат, и вы воочию видите expireAt. Используйте голый id модели (z-image, без суффиксов вроде /text-to-image, иначе будет 400):

# 1. Отправка задачи
curl -s https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "z-image",
    "input": { "prompt": "a red apple on a wooden table" }
  }'
# → {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}

# 2. Опрос финального состояния с taskId из предыдущего шага, чтение url и expireAt
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-xxxx \
  -H "Authorization: Bearer $HIAPI_API_KEY"
# после того как data.status станет "success", появятся data.output[0].url / .expireAt

Если аутентификация не удалась, возвращается HTTP 401 + {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}} — это проблема ключа, а не истечения. Если задача не найдена — {"code":404,"data":null,"message":"task not found"} — обычно это опечатка в taskId или ключ от другого окружения.

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

FAQ

Вопрос: в каком формате expireAt? Ответ: целочисленная Unix-метка времени (секунды), например 1792432981, не ISO-строка. Для определения истечения используйте now >= expireAt.

Вопрос: после истечения ссылки можно ли повторным GET задачи «продлить» ссылку? Ответ: нет. Повторный GET по тому же taskId вернёт ту же исходную url и исходный expireAt, объект уже удалён. Чтобы снова получить скачиваемый результат, нужно перезапустить задачу (с повторной оплатой).

Вопрос: после истечения возвращается 403 или 404? Ответ: HTTP 404, причём body — это text/html страница «Not Found» от Cloudflare, а не байты изображения и не XML AccessDenied. Если ваша логика скачивания принимает только 200, обрабатывайте «всё, что не 200» как ошибку.

Вопрос: срок действия фиксирован — 7 дней? Ответ: в измеренном образце — 7 дней (604800 секунд), но ориентируйтесь на expireAt каждого вывода, не вписывайте количество дней жёстко в код.

Вопрос: как надёжнее всего скачивать пакет задач? Ответ: по порядку завершения — у кого раньше success, у того раньше скачивайте байты. У завершившихся первыми выводов expireAt тоже наступает раньше, откладывание единовременного скачивания на конец часто приводит к попаданию в предэкспирационное окно.

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

Все статьи →

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

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

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