Skip to content

Материалы (Assets)

API материалов хранит референсные материалы — изображения, видео, аудио, — которые видеомодели Seedance могут принимать на вход. Вы загружаете материал один раз, дожидаетесь обработки в вышестоящем сервисе материалов, а затем ссылаетесь на него как на asset://<asset_id> в запросе генерации видео вместо того, чтобы каждый раз передавать один и тот же публичный URL.

Это API управления, а не API генерации. RouteAPI аутентифицирует вызов вашим API-ключом, передаёт его в вышестоящий сервис материалов и возвращает ответ вышестоящего сервиса. Вызовы этих эндпоинтов не тарифицируются как использование моделей. Кроме того, они находятся вне поверхности OpenAI SDK, поэтому используйте обычный HTTP, а не клиент SDK.

  1. Создайте группу материалов через POST /v1/asset-groups.
  2. Добавьте материал в эту группу через POST /v1/assets, передав публично доступный для скачивания URL.
  3. Опрашивайте материал через GET /v1/assets/{assetID}, пока его статус не станет Active. Обработка выполняется асинхронно.
  4. Сошлитесь на материал как на asset://<asset_id> в metadata.content запроса POST /v1/video/generations. См. Использование материала в запросе Seedance и Seedance.
  5. Опрашивайте задачу видео как обычно. Запросы видео с материалами отправляются в вышестоящий сервис один раз; они не повторяются и не переключаются на другой канал.
МетодПутьНазначениеВыделяет место под материалы
POST/v1/asset-groupsСоздать группу материаловДа
GET/v1/asset-groupsСписок группНет
GET/v1/asset-groups/{groupID}Получить одну группуНет
DELETE/v1/asset-groups/{groupID}Удалить группуНет
PUT/v1/asset-groups/{groupID}Переименовать группуНет
POST/v1/assetsДобавить материал в группуДа
GET/v1/assetsСписок материалов в группеНет
GET/v1/assets/{assetID}Получить один материал (для опроса)Нет
DELETE/v1/assets/{assetID}Удалить материалНет
PUT/v1/assets/{assetID}Переименовать материалНет
POST/v1/assets/verify-sessionsСоздать сеанс верификации личностиДа
GET/v1/assets/verify-sessions/{sessionID}Получить сеанс верификацииНет

Передайте API-ключ моделей в стандартном заголовке:

Authorization: Bearer sk-your-routeapi-key

Ключ идентифицирует аккаунт RouteAPI. Материалы изолированы по аккаунтам: все API-ключи одного аккаунта видят одни и те же группы, материалы и сеансы верификации, и никакой другой аккаунт их не видит. Ключ никогда не отправляется в вышестоящий сервис — вместо него RouteAPI использует отдельные вышестоящие учётные данные от вашего имени.

Первое использование и ключ пула материалов

Section titled “Первое использование и ключ пула материалов”

Каждый аккаунт привязан к одним вышестоящим учётным данным, которые сервис материалов использует для разделения материалов разных аккаунтов. Привязка назначается автоматически при первом вызове аккаунтом создающего эндпоинта:

  • POST /v1/asset-groups
  • POST /v1/assets
  • POST /v1/assets/verify-sessions

После назначения привязка становится постоянной для аккаунта и используется всеми последующими вызовами, включая запросы видео, которые ссылаются на материалы asset://.

Эндпоинты чтения и удаления никогда не выделяют место. Пока привязки нет:

ВызовОтвет
GET /v1/asset-groups200, пустой список: {"total": 0, "asset_groups": []}
Любой другой GET или DELETE404, {"error": "not found"}

То есть пустой список групп — нормальный ответ для нового аккаунта, а 404 на конкретный материал или группу до первого использования означает «у этого аккаунта ещё нет места под материалы», а не «неверный ID».

Маршрутизация групп на учётные данные — деталь конфигурации сервиса. Если для вашей группы не настроен канал материалов, первый создающий вызов завершится ошибкой 503 asset_pool_exhausted или 503 asset_pool_misconfigured вместо выделения места. Повторите попытку позже или обратитесь в поддержку, если ошибка сохраняется.

Создать группу материалов

Section titled “Создать группу материалов”
POST /v1/asset-groups
Terminal window
curl https://api.routeapi.ai/v1/asset-groups \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "product-refs",
"description": "Reference material for product videos"
}'
ПолеТипОбязательноОписание
namestringДаИмя группы
descriptionstringНетОписание группы

Ответ:

{
"asset_group_id": "local_group_2c8186e6d8b44ffa73b371677bfe4af2",
"name": "product-refs",
"project_name": "default",
"status": "active"
}

Сохраните asset_group_id: он обязателен при добавлении материалов.

Список групп материалов

Section titled “Список групп материалов”
GET /v1/asset-groups
Terminal window
curl "https://api.routeapi.ai/v1/asset-groups?page=1&page_size=20" \
-H "Authorization: Bearer $ROUTEAPI_KEY"

Параметры постраничного вывода, такие как page и page_size, передаются как есть; применяются значения по умолчанию и максимальный размер страницы вышестоящего сервиса.

{
"total": 1,
"asset_groups": [
{
"asset_group_id": "local_group_2c8186e6d8b44ffa73b371677bfe4af2",
"group_type": "AIGC",
"project_name": "default",
"session_id": "",
"status": "active",
"created_at": 1792050332,
"updated_at": 1792050332
}
]
}

session_id заполняется только для групп, созданных через верификацию личности. У группы верифицированного человека group_type равен LivenessFace; у обычных групп — AIGC.

Получить группу материалов

Section titled “Получить группу материалов”
Terminal window
curl https://api.routeapi.ai/v1/asset-groups/local_group_2c8186e6d8b44ffa73b371677bfe4af2 \
-H "Authorization: Bearer $ROUTEAPI_KEY"

Ответ с деталями вышестоящего сервиса может вернуть пустую строку status. Когда нужно решить, пригодна ли группа, используйте значение из ответа на список или из ответа на создание.

Удалить группу материалов

Section titled “Удалить группу материалов”
Terminal window
curl -X DELETE https://api.routeapi.ai/v1/asset-groups/local_group_2c8186e6d8b44ffa73b371677bfe4af2 \
-H "Authorization: Bearer $ROUTEAPI_KEY"
{ "deleted": "local_group_2c8186e6d8b44ffa73b371677bfe4af2" }

Удаление необратимо.

Переименовать группу материалов

Section titled “Переименовать группу материалов”
Terminal window
curl -X PUT https://api.routeapi.ai/v1/asset-groups/local_group_2c8186e6d8b44ffa73b371677bfe4af2 \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "new_group_name"}'
{ "name": "new_group_name", "updated": "local_group_2c8186e6d8b44ffa73b371677bfe4af2" }
POST /v1/assets

Один материал на запрос. Передайте группу, имя и ровно один исходный URL.

ПолеТипОбязательноОписание
asset_group_idstringДаГруппа, к которой относится материал
asset_namestringДаИмя используется только для поиска; на генерацию оно не влияет
image_urlstringОдно из трёхПубличный URL изображения
video_urlstringОдно из трёхПубличный URL видео
audio_urlstringОдно из трёхПубличный URL аудиофайла
asset_typestringНетImage, Video или Audio; при отсутствии выводится из поля URL
descriptionstringНетОписание материала

Передайте ровно одно из полей image_url, video_url и audio_url; вышестоящий сервис отклоняет запросы без них или с несколькими. URL должен скачиваться из публичного интернета без аутентификации и дополнительных заголовков. Полезная нагрузка Base64 и внутренние адреса не поддерживаются, а URL должен оставаться доступным до завершения обработки.

Terminal window
curl https://api.routeapi.ai/v1/assets \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"asset_group_id": "local_group_2c8186e6d8b44ffa73b371677bfe4af2",
"asset_name": "product-front",
"image_url": "https://cdn.example.com/product-front.jpg"
}'
{
"asset_id": "local_asset_25e4d0cb018fb5802bf4e466f99707d0",
"asset_group_id": "local_group_2c8186e6d8b44ffa73b371677bfe4af2",
"asset_name": "product-front",
"asset_type": "Image",
"asset_uri": "asset://local_asset_25e4d0cb018fb5802bf4e466f99707d0",
"status": "Processing"
}

Успешное создание означает, что запрос принят, а не что материал уже пригоден к использованию. asset_uri — это форма, которую нужно использовать в запросах видео.

СтатусЗначениеЧто делать
ProcessingЕщё загружаетсяПродолжайте опрос
ActiveГотов к использованиюСошлитесь на него в запросе видео
FailedЗагрузка не удаласьПроверьте требования к формату и размеру и добавьте заново

Используйте этот эндпоинт для опроса каждые 5–10 секунд с общим тайм-аутом. Обработка обычно занимает от секунд до десятков секунд; видеоматериалы и периоды высокой нагрузки обрабатываются дольше.

Terminal window
curl https://api.routeapi.ai/v1/assets/local_asset_25e4d0cb018fb5802bf4e466f99707d0 \
-H "Authorization: Bearer $ROUTEAPI_KEY"
{
"asset_id": "local_asset_25e4d0cb018fb5802bf4e466f99707d0",
"asset_group_id": "local_group_2c8186e6d8b44ffa73b371677bfe4af2",
"status": "Active",
"asset_uri": "asset://local_asset_25e4d0cb018fb5802bf4e466f99707d0",
"url": "https://..."
}

url — временный подписанный адрес для скачивания. Не сохраняйте его; для генерации используйте asset_uri.

Отсутствующий или удалённый материал возвращает 404 от вышестоящего сервиса, например:

{ "details": "record not found", "error": "asset not found in database" }

Список и удаление материалов

Section titled “Список и удаление материалов”
Terminal window
# List — asset_group_id is required
curl "https://api.routeapi.ai/v1/assets?asset_group_id=local_group_2c8186e6d8b44ffa73b371677bfe4af2" \
-H "Authorization: Bearer $ROUTEAPI_KEY"
# Delete
curl -X DELETE https://api.routeapi.ai/v1/assets/local_asset_25e4d0cb018fb5802bf4e466f99707d0 \
-H "Authorization: Bearer $ROUTEAPI_KEY"
{ "deleted": "local_asset_25e4d0cb018fb5802bf4e466f99707d0" }

Удаление материала ломает любой новый запрос видео, который на него ссылается.

Переименовать материал

Section titled “Переименовать материал”
Terminal window
curl -X PUT https://api.routeapi.ai/v1/assets/local_asset_25e4d0cb018fb5802bf4e466f99707d0 \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "new_asset_name"}'
{ "updated": "local_asset_25e4d0cb018fb5802bf4e466f99707d0" }

После переименования ответы с деталями материала и списком возвращают новое имя.

Сеансы верификации личности

Section titled “Сеансы верификации личности”

Материалы, содержащие лицо реального человека, требуют предварительного согласия этого человека. Сеанс верификации создаёт отдельную группу для материалов этого человека; материалы, добавленные в неё, проверяются на согласованность лица.

POST /v1/assets/verify-sessions

Тело может быть пустым ({} или вовсе без тела). callback_url принимается, но не используется для перенаправления.

Terminal window
curl https://api.routeapi.ai/v1/assets/verify-sessions \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{}'
{
"session_id": "asset_sess_5e7860e76613dd51a4867bdcbea6076b",
"status": "pending",
"h5_link": "https://...one-time-link...",
"callback_url": ""
}

Передавайте h5_link только тому человеку, который будет проходить верификацию. Ссылка содержит одноразовые учётные данные и даёт доступ к странице верификации; не размещайте её в публичных логах, на скриншотах или в групповых чатах.

Terminal window
curl https://api.routeapi.ai/v1/assets/verify-sessions/asset_sess_5e7860e76613dd51a4867bdcbea6076b \
-H "Authorization: Bearer $ROUTEAPI_KEY"
statusЗначение
pendingОжидание человека или обработка ещё продолжается
succeededВерификация пройдена; asset_group_id заполнен
failedВерификация не пройдена; прочитайте error
{
"session_id": "asset_sess_a8af6fab34f694ada40c22521448f579",
"status": "succeeded",
"result_code": "",
"error": "",
"asset_group_id": "group-20261015202316-4t5jt",
"project_name": "default",
"created_at": 1792066965,
"updated_at": 1792067203
}

Вебхука или перенаправления обратно в ваш сервис нет — браузер человека завершает работу на странице результата, принадлежащей вышестоящему сервису. Опрашивайте сеанс, пока status не станет succeeded (обычно в течение нескольких минут), затем добавьте материалы этого человека в возвращённый asset_group_id. result_code сейчас всегда пуст; используйте status. Сеанс в состоянии failed с error, например verification expired, нужно создавать заново.

Использование материала в запросе Seedance

Section titled “Использование материала в запросе Seedance”

Сошлитесь на материал внутри metadata.content запроса генерации видео, используя asset_uri, возвращённый API материалов:

Terminal window
curl https://api.routeapi.ai/v1/video/generations \
-H "Authorization: Bearer $ROUTEAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedance-2-0-fast-260128",
"prompt": "The product in image 1 rotates slowly",
"metadata": {
"content": [
{ "type": "text", "text": "The product in image 1 rotates slowly" },
{
"type": "image_url",
"image_url": { "url": "asset://local_asset_25e4d0cb018fb5802bf4e466f99707d0" },
"role": "reference_image"
}
],
"duration": 4,
"resolution": "480p",
"ratio": "1:1"
}
}'

Используйте ID видеомодели Seedance из GET /v1/models, поддерживающей генерацию видео; см. Models. Формат запроса для Seedance, включая роли metadata.content и ограничения конкретных моделей, описан в разделе Seedance.

Правила, вытекающие из контракта сервиса материалов:

  • Пара type/role должна соответствовать типу материала: image_url с reference_image, video_url с reference_video, audio_url с reference_audio.
  • Ссылаться можно только на материалы в статусе Active.
  • Текст промпта ссылается на материалы по порядковому номеру («image 1», «video 1»), который считается внутри каждого типа в порядке content. Не помещайте ID материалов в промпт.
  • Материалы с реальными людьми должны быть из верифицированной группы; иначе вышестоящий сервис может отклонить или провалить задачу.

RouteAPI определяет ссылку по любому строковому значению JSON, которое начинается с asset:// (без учёта регистра). Такой запрос закрепляется за вашим каналом материалов и отправляется один раз, без повторных попыток и переключения на другой канал. В следующих случаях запрос отклоняется локально:

СтатусКодПричина
400asset_key_requiredТело ссылается на asset://, но у аккаунта ещё нет места под материалы. Сначала создайте группу и материал
400asset_remix_conflictРемикс задачи без материалов пытается сослаться на материал asset://
400asset_channel_conflictAPI-ключ закреплён за конкретным каналом, который не является вашим каналом материалов
400asset_model_unsupportedМодель не поддерживается вашим каналом материалов
503asset_key_unavailableВышестоящие учётные данные, привязанные к аккаунту, неисправны или отключены

Эти ошибки используют форму ошибки задачи {"code": ..., "message": ..., "data": ...}.

  • Тело запроса — тела POST и PUT читаются с ограничением 1 MiB. Тело большего размера возвращает 413 до того, как что-либо будет отправлено в вышестоящий сервис. Сам материал никогда не загружается через тело; передавайте URL.
  • Форма тела — непустое тело POST или PUT должно быть JSON-объектом. Массивы, отдельные строки, null и некорректный JSON возвращают 400, не доходя до вышестоящего сервиса. Тела GET и DELETE игнорируются.
  • Тело переименования — тело PUT должно содержать непустое строковое поле name (ключ в нижнем регистре). Если name отсутствует, пустое или не строка, возвращается 400, запрос не доходит до вышестоящего сервиса.
  • Тело ответа — ответы вышестоящего сервиса размером более 10 MiB, а также ответы, которые не удалось прочитать, возвращают 502.
  • Тайм-аут — вызов вышестоящего сервиса имеет фиксированный тайм-аут 60 секунд; его истечение сообщается как 502.
  • project_name — если это поле присутствует в теле POST или PUT, оно удаляется перед пересылкой в любом регистре.
  • Ошибки владения — если вышестоящий сервис отвечает 403 с отказом по владению («you do not own» / «access denied»), RouteAPI вместо этого возвращает 404 {"error": "not found"}, чтобы ресурс выглядел несуществующим, а не запрещённым.
  • Сбои вышестоящих учётных данных — ответ 401 от вышестоящего сервиса превращается в 503 asset_key_unavailable и помечает привязку аккаунта как неисправную (см. выше). Ответ 402 от вышестоящего сервиса или ошибка вышестоящего сервиса, тело которой указывает на проблему с биллингом, превращается в 503 asset_service_unavailable.

Остальные коды статусов и тела ответов вышестоящего сервиса передаются без изменений, включая ошибки валидации вышестоящего сервиса. Собственные ошибки RouteAPI имеют одну из трёх форм:

{ "error": "not found" }
{ "error": "<message>", "code": "asset_pool_busy" }
{
"error": {
"message": "token.invalid (request id: ...)",
"type": "error",
"code": ""
}
}

Третья форма приходит из общего middleware аутентификации и ограничения частоты, поэтому проверяйте, является ли error строкой или объектом. Текст локального message сейчас на китайском — для первых двух форм ориентируйтесь на HTTP-статус и поле code, а не на сообщение.

СтатусКодЗначениеЧто делать
400—Тело не является JSON-объектом или вышестоящий сервис отклонил параметрыИсправьте запрос; не повторяйте его без изменений
401—API-ключ отсутствует, недействителен или удалёнПроверьте Authorization
404—Неизвестный материал, группа или сеанс; либо у этого аккаунта ещё нет места под материалыПроверьте ID; если аккаунт новый, сначала создайте группу
413—Тело запроса превышает 1 MiBПередайте URL вместо встроенных данных
429—Сработало ограничение частотыЗамедлите опрос и повторите позже
500asset_pool_internal_errorRouteAPI не смог прочитать или записать собственное состояние материаловПовторите позже
500—RouteAPI не смог прочитать состояние материалов аккаунтаПовторите позже
502—Вышестоящий сервис недоступен, превысил тайм-аут или вернул нечитаемый или слишком большой ответПовторите позже
503asset_key_unavailableВышестоящие учётные данные аккаунта неисправны или отключеныОбратитесь в поддержку; повтор не поможет
503asset_pool_exhaustedУ вашей группы нет канала материалов или нет учётных данных для выделенияПовторите позже или обратитесь в поддержку
503asset_pool_busyУчётные данные есть, но сейчас ни одни не удалось выделитьПовторите позже
503asset_pool_misconfiguredВаша группа сопоставлена более чем с одним каналом материаловОбратитесь в поддержку
503asset_channel_unavailableСам канал материалов отключён или настроен неверноПовторите позже или обратитесь в поддержку
503asset_service_unavailableБаланс вышестоящего аккаунта или критический сбойПовторите позже или обратитесь в поддержку

Вызовы материалов не имеют стоимости модели, но при включённом ограничении частоты модельных запросов на платформе они учитываются в нём, как и любой другой запрос /v1. Общая модель ошибок описана в разделе Ошибки и отладка, а о том, как тарифицируется генерация видео, использующая эти материалы, — в разделе Цены моделей.