Задачи в API, создание, опрос и результат
Как запустить картинку, видео, музыку, озвучку или документ запросом POST /v1/tasks, дождаться готовности опросом и забрать файлы.
Создайте задачу
curl https://epicai.ru/v1/tasks \
-H "Authorization: Bearer $EPICAI_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: video-001" \
-d '{
"model": "kling",
"prompt": "Кошка идёт по подоконнику, за окном дождь",
"parameters": {"scenario": "t2v", "engine": "v3", "quality": "std", "duration": 5, "aspect_ratio": "16:9"}
}'
Так запускаются картинки, видео, музыка, озвучка, расшифровка речи и документы. Для текстовых моделей остаётся чат. В теле запроса всего восемь полей, лишние epicai отклоняет ответом 400 unknown_parameter.
| Поле | Что передать |
|---|---|
model | Имя модели из GET /v1/models. Обязательное |
prompt | Описание или текст задачи. Предельную длину и обязательность называют поля prompt_max и prompt_required модели |
parameters | Объект с настройками модели. Допустимые имена и значения лежат в parameters ответа GET /v1/models/{id}. Незаданные берутся по умолчанию, как на сайте |
images, videos, audios | Списки входных файлов, см. ниже |
source | Готовая задача и номер её результата для операций вроде увеличения картинки или продления трека, см. операции над результатом |
webhook_url | Адрес для уведомления о завершении, см. вебхуки |
Незнакомое имя в parameters и значение вне списка дают 400 invalid_parameter, а в param стоит parameters.имя. Молча подставлять умолчание epicai не станет: опечатка превратилась бы в платный запуск с другими настройками.
В ответ приходит задача. Код 201, у части моделей 202 с тем же телом. Заголовок Location ведёт на адрес задачи.
{
"id": "task_7fa4be5e14351e3dff994aa3",
"object": "task",
"type": "video",
"model": "kling",
"status": "in_progress",
"created_at": 1793114499,
"started_at": 1793114499,
"finished_at": null,
"price": {"tokens": 75000, "charged": 0},
"parameters": {"scenario": "t2v", "engine": "v3", "quality": "std", "duration": 5, "aspect_ratio": "16:9", "sound": false, "shots_mode": "off"}
}
В parameters вернулись все настройки, с которыми работает задача, включая подставленные по умолчанию. Цена в price.tokens зафиксирована. Заранее её можно узнать запросом POST /v1/quote (подробнее о цене задачи).
Дождитесь результата
curl https://epicai.ru/v1/tasks/task_7fa4be5e14351e3dff994aa3 \
-H "Authorization: Bearer $EPICAI_API_KEY"
Запрос сам проверяет, что с задачей у вендора, поэтому ждать фонового обхода не нужно. Пока задача в работе, ответ содержит заголовок Retry-After: 3. Чаще раза в 3 секунды спрашивать нет смысла. Срок зависит от модели и нагрузки у вендора.
status | Значение |
|---|---|
queued | Задача принята, вендору ещё не передана |
in_progress | Вендор работает. Цена зарезервирована, price.charged равно 0 |
succeeded | Готово. Файлы в output, цена списана и записана в price.charged |
failed | Не получилось. Причина в error, токены не списаны |
Первые два статуса промежуточные, последние два окончательные. Тот же цикл на Python:
import os
import time
import requests
API = "https://epicai.ru/v1"
headers = {"Authorization": "Bearer " + os.environ["EPICAI_API_KEY"]}
reply = requests.post(API + "/tasks", headers=headers, json={
"model": "kling",
"prompt": "Кошка идёт по подоконнику, за окном дождь",
"parameters": {"scenario": "t2v", "engine": "v3", "quality": "std", "duration": 5},
})
reply.raise_for_status()
task = reply.json()
while task["status"] in ("queued", "in_progress"):
time.sleep(5)
reply = requests.get(API + "/tasks/" + task["id"], headers=headers)
reply.raise_for_status()
task = reply.json()
if task["status"] == "succeeded":
for item in task["output"]:
print(item["type"], item["url"])
else:
print(task["error"]["code"], task["error"]["message"])
Не полагайтесь на то, что свежая задача придёт в работе. Если вендор ответил сразу, она может прийти уже со статусом succeeded. Чужая или несуществующая задача даёт 404 task_not_found.
Заберите файлы
"status": "succeeded",
"price": {"tokens": 75000, "charged": 75000},
"output": [
{"type": "video", "url": "https://epicai.ru/storage/api/7fa4be5e14351e3dff994aa3/1.mp4", "mime": "video/mp4", "bytes": 5236392}
],
"expires_at": 1793719429
В output лежат ссылки на готовые файлы с типом (image, video, audio, text или document), mime и размером в байтах. У картинок есть ещё width и height. Ссылка открывается без ключа, поэтому её можно отдать браузеру или плееру. Вместе с главным файлом бывает вспомогательный .json или .txt, например описание треков у музыки и текст расшифровки. У каждого вида свой состав результата, смотрите статьи про картинки, видео, музыку, озвучку и расшифровку и документы.
ВажноФайлы хранятся 7 суток после завершения, срок назван в
expires_at. Потом epicai стирает их, а задача остаётся с пустымoutputи признакомexpired: true. Сохраните результат у себя раньше.
У задачи со статусом failed вместо файлов приходит объект error.
"status": "failed",
"price": {"tokens": 75000, "charged": 0},
"error": {"code": "task_timeout", "message": "Нейросеть не завершила задачу вовремя. Токены не списаны. Повторите запрос"}
Опирайтесь на code. Он стабилен, а текст написан для человека. Среди кодов встречаются content_filter (описание или файл отклонил фильтр безопасности нейросети), input_unavailable (нейросеть не смогла скачать входной файл), empty_result (вендор завершил работу без файла) и task_timeout. Полный перечень общих ошибок ищите в Ошибках API.
Посмотрите список задач
curl "https://epicai.ru/v1/tasks?status=succeeded&model=kling&limit=20" \
-H "Authorization: Bearer $EPICAI_API_KEY"
Ответ — объект list с массивом data, где каждая задача выглядит как в GET /v1/tasks/{id}. Свежие идут первыми. В список попадают задачи всех ключей владельца в том же пространстве, личном или организации.
| Параметр | Значение |
|---|---|
limit | От 1 до 100, по умолчанию 20 |
after | Номер задачи, после которой продолжить. Берите его из next_after прошлого ответа, он есть, когда has_more равно true |
status | queued, in_progress, succeeded или failed |
model | Имя модели |
Передайте входные файлы
Картинки-референсы, видео для перерисовки и записи идут в полях images, videos и audios. Каждое поле — массив строк. Строка может быть ссылкой http(s) или данными data:…;base64,….
{
"model": "kling",
"prompt": "Камера медленно приближается",
"parameters": {"scenario": "i2v", "engine": "v3", "quality": "std", "duration": 5},
"images": ["https://example.com/photo.jpg"]
}
- Картинка — PNG, JPEG или WebP до 10 МБ. Присланные данные проверяются по содержимому, а не по расширению. В виде данных строка выглядит как
data:image/png;base64,…. - Видео — MP4, MOV или WebM, звук — MP3, WAV, M4A, OGG, FLAC, AAC или WebM, данные записываются как
data:video/…;base64,…иdata:audio/…;base64,…. Список форматов и предельный размер у каждой модели свои, их называет полеinput_filesвGET /v1/models/{id}. Если модель предел не задаёт, он равен 100 МБ. - Видео и звук epicai скачивает и сохраняет всегда, затем сам измеряет длительность. От неё зависит цена, и верить числу со слов клиента нельзя.
- Ссылка должна вести на публичный сервер по порту 80 или 443, без логина и пароля, длиной до 2000 знаков. До трёх перенаправлений epicai пройдёт, адреса во внутренних сетях отклонит.
Сколько файлов принимает модель, написано в полях inputs и inputs_by её описания. У моделей с режимами, как у Kling, число файлов зависит от значения параметра, и inputs_by показывает его по каждому значению. Лишние файлы дают 400 invalid_image (картинки) или 400 invalid_input (видео и звук), нехватка обязательных картинок — 400 missing_required_parameter. Весь запрос не больше 12 МБ (иначе 413 request_too_large), поэтому крупные видео передавайте ссылкой. Присланные файлы epicai стирает, когда задача завершилась.
Защититесь от двойного запуска
Если связь оборвалась после отправки запроса, неизвестно, создалась ли задача. Повтор без защиты запустит вторую платную. Заголовок Idempotency-Key (до 64 знаков, латиница, цифры и символы . _ : -) связывает повтор с первым запросом. Тот же ключ с тем же телом вернёт уже созданную задачу с кодом 200 и заголовком Idempotent-Replayed: true, и ничего не спишется второй раз. Тот же ключ с другой моделью, текстом, параметрами, файлами или вебхуком даст 409 idempotency_conflict. Для каждой новой задачи берите новое значение.
Учтите пределы
- У одного ключа по умолчанию не больше 20 задач в работе. Двадцать первая получает 429
too_many_active_tasksиRetry-After: 10. - Задача, которая не завершилась за 100 минут, переходит в
failedс кодомtask_timeout, резерв возвращается. - Суточный и месячный потолки ключа проверяются по цене задачи в момент создания. Остальные пределы перечислены в Лимитах API.
Не нашли ответ?
Посмотрите частые вопросы или напишите в поддержку.