Документация NeuroAPI
Генерация

Видео

Асинхронная генерация видео, polling и безопасные повторы

Видео создаётся не одним длинным запросом, а как задача: вы отправляете параметры, получаете ID, периодически проверяете состояние и скачиваете файл после завершения.

  1. Создать — POST возвращает ID задачи.
  2. Дождаться — GET сообщает текущий статус.
  3. Скачать — Контент доступен после completed.

Важно: Ответ с id означает, что задача уже принята. Сразу сохраните ID в своей базе и не повторяйте create POST — дальше используйте только запрос статуса.

OpenAI и Alibaba-compatible native video для Wan/HappyHorse →

До первого запроса

  1. Получите модели через GET /v1/models своим API-ключом.
  2. Убедитесь, что в ответе есть нужная видеомодель. Набор моделей зависит от тарифа, ключа и текущей доступности.
  3. Используйте формат именно с этой страницы. Наличие модели в /v1/models означает доступность модели ключу, но не обещает поддержку этой модели во всех форматах API.

Информация: Если ни одной видеомодели нет в /v1/models, этот ключ сейчас не может создавать видео. Смена имени модели в запросе не добавит доступ.

OpenAI-compatible Video

Стабильный

ДействиеМетод и путьРезультат
СоздатьPOST /v1/videosЗадача с полями id и status
ПроверитьGET /v1/videos/{id}Текущий статус и progress, если доступен
СкачатьGET /v1/videos/{id}/contentГотовый видеофайл

Параметры создания

ПолеОбязательностьНазначение
modelДаТочный ID из GET /v1/models или каталога цен
promptЗависит от моделиОписание сцены, движения камеры и ограничений
secondsРекомендуетсяДлительность ролика; допустимые значения зависят от модели
sizeРекомендуетсяРазмер кадра, например 1280x720; задаёт также соотношение сторон
input_reference.urlТолько image-to-videoПубличная HTTPS-ссылка на исходный кадр; поддержка зависит от модели

Информация: В стабильном формате используйте seconds и size. Поля duration и aspect_ratio показаны ниже только в тех Beta-форматах, где они входят в контракт.

cURL

curl https://neuroapi.host/v1/videos \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-v3_videos",
    "prompt": "Кинематографичный рассвет над озером, без текста и логотипов",
    "seconds": 5,
    "size": "1280x720"
  }'

Python · requests

import requests

response = requests.post(
    "https://neuroapi.host/v1/videos",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "kling-v3_videos",
        "prompt": "Кинематографичный рассвет над озером",
        "seconds": 5,
        "size": "1280x720",
    },
    timeout=90,
)
response.raise_for_status()
task = response.json()
task_id = task["id"]
print(task_id, task["status"])

Node.js · TypeScript

const response = await fetch("https://neuroapi.host/v1/videos", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "kling-v3_videos",
    prompt: "Кинематографичный рассвет над озером",
    seconds: 5,
    size: "1280x720",
  }),
});

if (!response.ok) throw new Error(await response.text());
const task = await response.json();
console.log(task.id, task.status);

Из изображения в видео

Передавайте исходный кадр только модели, которая поддерживает image-to-video. Ссылка должна быть доступна серверу по публичному HTTPS без авторизации и возвращать реальное изображение.

cURL · изображение → видео

curl https://neuroapi.host/v1/videos \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-v3_videos",
    "prompt": "Медленное движение камеры вперёд, естественное движение воды",
    "seconds": 5,
    "size": "1280x720",
    "input_reference": {
      "url": "https://example.com/start-frame.png"
    }
  }'

Что вернёт создание

{
  "id": "video_abc123",
  "status": "queued",
  "model": "kling-v3_videos",
  "created_at": 1785000000
}

Поле id — единственный надёжный ключ для продолжения работы. HTTP-код создания может зависеть от конкретного видео-контракта; ориентируйтесь на успешный 2xx и наличие ID.

Статусы и опрос задачи

СтатусЗначение
queuedЗадача принята и ожидает вычислительных ресурсов
in_progressГенерация выполняется; продолжайте редкий polling
completedРезультат готов; можно запрашивать /content
failedЗадача завершилась ошибкой; POST автоматически не повторяйте

Первый GET отправляйте примерно через 5 секунд, затем увеличивайте интервал до 15 секунд. Частый polling не ускоряет генерацию. Сетевой таймаут отдельного GET не означает ошибку задачи: повторите только GET с тем же ID.

Python

import time
import requests

def wait_for_video(task_id, timeout=1800):
    deadline = time.monotonic() + timeout
    headers = {"Authorization": "Bearer YOUR_API_KEY"}
    delay = 5

    while time.monotonic() < deadline:
        response = requests.get(
            f"https://neuroapi.host/v1/videos/{task_id}",
            headers=headers,
            timeout=30,
        )
        response.raise_for_status()
        task = response.json()

        if task["status"] == "completed":
            return task
        if task["status"] == "failed":
            message = task.get("error", {}).get("message", "Генерация не удалась")
            raise RuntimeError(message)

        time.sleep(delay)
        delay = min(delay + 2, 15)

    raise TimeoutError("Задача ещё выполняется; сохраните task_id и проверьте позже")

TypeScript

async function waitForVideo(taskId: string) {
  let delayMs = 5_000;

  for (;;) {
    const response = await fetch(
      `https://neuroapi.host/v1/videos/${encodeURIComponent(taskId)}`,
      { headers: { Authorization: "Bearer YOUR_API_KEY" } },
    );
    if (!response.ok) throw new Error(await response.text());

    const task = await response.json();
    if (task.status === "completed") return task;
    if (task.status === "failed") {
      throw new Error(task.error?.message ?? "Генерация не удалась");
    }

    await new Promise((resolve) => setTimeout(resolve, delayMs));
    delayMs = Math.min(delayMs + 2_000, 15_000);
  }
}

После перезапуска приложения

Храните task_id, выбранную модель и время создания в своей базе. После перезапуска не создавайте новую задачу: возобновите GET /v1/videos/{id}. Это предотвращает двойную генерацию и двойные расходы.

Получение файла

Вызывайте /content только после статуса completed. Ответ может перенаправить на временное файловое хранилище, поэтому HTTP-клиент должен разрешать редиректы. Сохраняйте бинарный ответ как файл, а не пытайтесь разобрать его как JSON.

cURL

curl -L https://neuroapi.host/v1/videos/VIDEO_ID/content \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o result.mp4

Kling-compatible API

Бета

Для Kling можно использовать его нативную структуру запросов. В GET /v1/models модель называется, например, kling-v3_videos, а в поле model_name нативного запроса — kling-v3.

ДействиеПутьЧто сохранить
Создать text-to-videoPOST /kling/v1/videos/text2videodata.task_id
Проверить задачуGET /kling/v1/videos/text2video/{task_id}data.task_status

Kling-compatible · Бета

curl https://neuroapi.host/kling/v1/videos/text2video \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model_name": "kling-v3",
    "prompt": "Панорамный пролёт над ночным городом",
    "duration": "5",
    "aspect_ratio": "16:9"
  }'

# Сохраните data.task_id:
curl https://neuroapi.host/kling/v1/videos/text2video/TASK_ID \
  -H "Authorization: Bearer YOUR_API_KEY"

Ответ и статусы Kling

{
  "code": 0,
  "message": "",
  "data": {
    "task_id": "909940330328358924",
    "task_status": "submitted",
    "created_at": 1785000000000,
    "updated_at": 1785000000000
  }
}

Ожидаемые состояния: submittedprocessingsucceed или failed. После succeed ссылка на файл находится в data.task_result.videos[].url. Скопируйте файл в своё хранилище: ссылка результата может быть временной.

Важно: У Kling нет отдельного /content в этом контракте. Не передавайте data.task_id в OpenAI-compatible /v1/videos/{id} и не смешивайте статусы succeed и completed.

Другие совместимые форматы

Бета

Эти контракты предназначены для переноса существующих интеграций. У каждого свои имена полей и ID: name или id. Не смешивайте URL создания и polling из разных форматов.

ФорматID в ответеПроверка
Gemini-compatiblename/v1beta/operations/{id}
Prediction-shapedid/replicate/v1/predictions/{id}

Gemini-compatible · Бета

curl "https://neuroapi.host/v1beta/models/veo-3.1:predictLongRunning" \
  -H "x-goog-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instances": [{"prompt": "Панорамный пролёт над ночным городом"}],
    "parameters": {"durationSeconds": 5, "aspectRatio": "16:9"}
  }'

# Сохраните name:
curl https://neuroapi.host/v1beta/operations/OPERATION_ID \
  -H "x-goog-api-key: YOUR_API_KEY"

Prediction-shaped · Бета

curl https://neuroapi.host/replicate/v1/models/veo-3.1/predictions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "input": {
      "prompt": "Панорамный пролёт над ночным городом",
      "duration": 5,
      "aspect_ratio": "16:9"
    }
  }'

curl https://neuroapi.host/replicate/v1/predictions/PREDICTION_ID \
  -H "Authorization: Bearer YOUR_API_KEY"

Ошибки, повторы и списание

СитуацияЧто делатьЧто со списанием
400/422 без IDИсправить параметры, модель или медиаЗадача не считается успешно созданной
429/503 без IDNeuroAPI уже делает один внутренний повтор; повторить позже, если ошибка сохраниласьОшибка доступности не тарифицируется как успешная генерация
2xx и есть IDСохранить ID; не повторять POST; опрашивать GETИтог определяется финальным состоянием задачи
202 после потери ответа upstreamНе повторять POST; опрашивать GET с тем же стабильным IDNeuroAPI восстанавливает задачу или автоматически возвращает резерв
Клиентский таймаут без ответа NeuroAPIНе отправлять POST вслепую; сначала проверить журнал или поддержкуИсход мог остаться неопределённым
Общий 500 без ID после долгого ожиданияНе повторять часто; сохранить время запроса и обратиться в поддержкуПроверить историю операций и баланс перед новым create
failedПрочитать безопасную ошибку и скорректировать запросНеуспешная генерация не должна списываться как успешная
Не скачивается completedПовторить только GET /content с тем же IDНовая генерация не создаётся

Важно: Не ставьте общий автоматический retry на POST /v1/videos. Если запрос успел запустить задачу, а ответ потерялся из-за прокси, нестабильной сети или таймаута, повтор создаст второе видео. Если NeuroAPI вернул 202 и ID, он сам продолжит восстановление — опрашивайте GET с этим ID. Автоматически повторять безопасно только GET статуса и GET контента.

Соединение create не остаётся открытым до конца генерации. Сохраните ID из 202: восстановленная задача и её результат появятся по тому же ID через обычный polling.