Материалы (Assets)
API материалов хранит референсные материалы — изображения, видео, аудио, — которые видеомодели Seedance могут принимать на вход. Вы загружаете материал один раз, дожидаетесь обработки в вышестоящем сервисе материалов, а затем ссылаетесь на него как на asset://<asset_id> в запросе генерации видео вместо того, чтобы каждый раз передавать один и тот же публичный URL.
Это API управления, а не API генерации. RouteAPI аутентифицирует вызов вашим API-ключом, передаёт его в вышестоящий сервис материалов и возвращает ответ вышестоящего сервиса. Вызовы этих эндпоинтов не тарифицируются как использование моделей. Кроме того, они находятся вне поверхности OpenAI SDK, поэтому используйте обычный HTTP, а не клиент SDK.
Рабочий процесс
Section titled “Рабочий процесс”- Создайте группу материалов через
POST /v1/asset-groups. - Добавьте материал в эту группу через
POST /v1/assets, передав публично доступный для скачивания URL. - Опрашивайте материал через
GET /v1/assets/{assetID}, пока его статус не станетActive. Обработка выполняется асинхронно. - Сошлитесь на материал как на
asset://<asset_id>вmetadata.contentзапросаPOST /v1/video/generations. См. Использование материала в запросе Seedance и Seedance. - Опрашивайте задачу видео как обычно. Запросы видео с материалами отправляются в вышестоящий сервис один раз; они не повторяются и не переключаются на другой канал.
Эндпоинты
Section titled “Эндпоинты”| Метод | Путь | Назначение | Выделяет место под материалы |
|---|---|---|---|
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} | Получить сеанс верификации | Нет |
Аутентификация
Section titled “Аутентификация”Передайте API-ключ моделей в стандартном заголовке:
Authorization: Bearer sk-your-routeapi-keyКлюч идентифицирует аккаунт RouteAPI. Материалы изолированы по аккаунтам: все API-ключи одного аккаунта видят одни и те же группы, материалы и сеансы верификации, и никакой другой аккаунт их не видит. Ключ никогда не отправляется в вышестоящий сервис — вместо него RouteAPI использует отдельные вышестоящие учётные данные от вашего имени.
Первое использование и ключ пула материалов
Section titled “Первое использование и ключ пула материалов”Каждый аккаунт привязан к одним вышестоящим учётным данным, которые сервис материалов использует для разделения материалов разных аккаунтов. Привязка назначается автоматически при первом вызове аккаунтом создающего эндпоинта:
POST /v1/asset-groupsPOST /v1/assetsPOST /v1/assets/verify-sessions
После назначения привязка становится постоянной для аккаунта и используется всеми последующими вызовами, включая запросы видео, которые ссылаются на материалы asset://.
Эндпоинты чтения и удаления никогда не выделяют место. Пока привязки нет:
| Вызов | Ответ |
|---|---|
GET /v1/asset-groups | 200, пустой список: {"total": 0, "asset_groups": []} |
Любой другой GET или DELETE | 404, {"error": "not found"} |
То есть пустой список групп — нормальный ответ для нового аккаунта, а 404 на конкретный материал или группу до первого использования означает «у этого аккаунта ещё нет места под материалы», а не «неверный ID».
Маршрутизация групп на учётные данные — деталь конфигурации сервиса. Если для вашей группы не настроен канал материалов, первый создающий вызов завершится ошибкой 503 asset_pool_exhausted или 503 asset_pool_misconfigured вместо выделения места. Повторите попытку позже или обратитесь в поддержку, если ошибка сохраняется.
Группы материалов
Section titled “Группы материалов”Создать группу материалов
Section titled “Создать группу материалов”POST /v1/asset-groupscurl 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" }'| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
name | string | Да | Имя группы |
description | string | Нет | Описание группы |
Ответ:
{ "asset_group_id": "local_group_2c8186e6d8b44ffa73b371677bfe4af2", "name": "product-refs", "project_name": "default", "status": "active"}Сохраните asset_group_id: он обязателен при добавлении материалов.
Список групп материалов
Section titled “Список групп материалов”GET /v1/asset-groupscurl "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 “Получить группу материалов”curl https://api.routeapi.ai/v1/asset-groups/local_group_2c8186e6d8b44ffa73b371677bfe4af2 \ -H "Authorization: Bearer $ROUTEAPI_KEY"Ответ с деталями вышестоящего сервиса может вернуть пустую строку status. Когда нужно решить, пригодна ли группа, используйте значение из ответа на список или из ответа на создание.
Удалить группу материалов
Section titled “Удалить группу материалов”curl -X DELETE https://api.routeapi.ai/v1/asset-groups/local_group_2c8186e6d8b44ffa73b371677bfe4af2 \ -H "Authorization: Bearer $ROUTEAPI_KEY"{ "deleted": "local_group_2c8186e6d8b44ffa73b371677bfe4af2" }Удаление необратимо.
Переименовать группу материалов
Section titled “Переименовать группу материалов”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" }Материалы
Section titled “Материалы”Добавить материал
Section titled “Добавить материал”POST /v1/assetsОдин материал на запрос. Передайте группу, имя и ровно один исходный URL.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
asset_group_id | string | Да | Группа, к которой относится материал |
asset_name | string | Да | Имя используется только для поиска; на генерацию оно не влияет |
image_url | string | Одно из трёх | Публичный URL изображения |
video_url | string | Одно из трёх | Публичный URL видео |
audio_url | string | Одно из трёх | Публичный URL аудиофайла |
asset_type | string | Нет | Image, Video или Audio; при отсутствии выводится из поля URL |
description | string | Нет | Описание материала |
Передайте ровно одно из полей image_url, video_url и audio_url; вышестоящий сервис отклоняет запросы без них или с несколькими. URL должен скачиваться из публичного интернета без аутентификации и дополнительных заголовков. Полезная нагрузка Base64 и внутренние адреса не поддерживаются, а URL должен оставаться доступным до завершения обработки.
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 — это форма, которую нужно использовать в запросах видео.
Статус материала
Section titled “Статус материала”| Статус | Значение | Что делать |
|---|---|---|
Processing | Ещё загружается | Продолжайте опрос |
Active | Готов к использованию | Сошлитесь на него в запросе видео |
Failed | Загрузка не удалась | Проверьте требования к формату и размеру и добавьте заново |
Получить материал
Section titled “Получить материал”Используйте этот эндпоинт для опроса каждые 5–10 секунд с общим тайм-аутом. Обработка обычно занимает от секунд до десятков секунд; видеоматериалы и периоды высокой нагрузки обрабатываются дольше.
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 “Список и удаление материалов”# List — asset_group_id is requiredcurl "https://api.routeapi.ai/v1/assets?asset_group_id=local_group_2c8186e6d8b44ffa73b371677bfe4af2" \ -H "Authorization: Bearer $ROUTEAPI_KEY"
# Deletecurl -X DELETE https://api.routeapi.ai/v1/assets/local_asset_25e4d0cb018fb5802bf4e466f99707d0 \ -H "Authorization: Bearer $ROUTEAPI_KEY"{ "deleted": "local_asset_25e4d0cb018fb5802bf4e466f99707d0" }Удаление материала ломает любой новый запрос видео, который на него ссылается.
Переименовать материал
Section titled “Переименовать материал”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 “Сеансы верификации личности”Материалы, содержащие лицо реального человека, требуют предварительного согласия этого человека. Сеанс верификации создаёт отдельную группу для материалов этого человека; материалы, добавленные в неё, проверяются на согласованность лица.
Создать сеанс
Section titled “Создать сеанс”POST /v1/assets/verify-sessionsТело может быть пустым ({} или вовсе без тела). callback_url принимается, но не используется для перенаправления.
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 только тому человеку, который будет проходить верификацию. Ссылка содержит одноразовые учётные данные и даёт доступ к странице верификации; не размещайте её в публичных логах, на скриншотах или в групповых чатах.
Получить сеанс
Section titled “Получить сеанс”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 материалов:
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:// (без учёта регистра). Такой запрос закрепляется за вашим каналом материалов и отправляется один раз, без повторных попыток и переключения на другой канал. В следующих случаях запрос отклоняется локально:
| Статус | Код | Причина |
|---|---|---|
| 400 | asset_key_required | Тело ссылается на asset://, но у аккаунта ещё нет места под материалы. Сначала создайте группу и материал |
| 400 | asset_remix_conflict | Ремикс задачи без материалов пытается сослаться на материал asset:// |
| 400 | asset_channel_conflict | API-ключ закреплён за конкретным каналом, который не является вашим каналом материалов |
| 400 | asset_model_unsupported | Модель не поддерживается вашим каналом материалов |
| 503 | asset_key_unavailable | Вышестоящие учётные данные, привязанные к аккаунту, неисправны или отключены |
Эти ошибки используют форму ошибки задачи {"code": ..., "message": ..., "data": ...}.
Ограничения и ошибки
Section titled “Ограничения и ошибки”- Тело запроса — тела
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 | — | Сработало ограничение частоты | Замедлите опрос и повторите позже |
| 500 | asset_pool_internal_error | RouteAPI не смог прочитать или записать собственное состояние материалов | Повторите позже |
| 500 | — | RouteAPI не смог прочитать состояние материалов аккаунта | Повторите позже |
| 502 | — | Вышестоящий сервис недоступен, превысил тайм-аут или вернул нечитаемый или слишком большой ответ | Повторите позже |
| 503 | asset_key_unavailable | Вышестоящие учётные данные аккаунта неисправны или отключены | Обратитесь в поддержку; повтор не поможет |
| 503 | asset_pool_exhausted | У вашей группы нет канала материалов или нет учётных данных для выделения | Повторите позже или обратитесь в поддержку |
| 503 | asset_pool_busy | Учётные данные есть, но сейчас ни одни не удалось выделить | Повторите позже |
| 503 | asset_pool_misconfigured | Ваша группа сопоставлена более чем с одним каналом материалов | Обратитесь в поддержку |
| 503 | asset_channel_unavailable | Сам канал материалов отключён или настроен неверно | Повторите позже или обратитесь в поддержку |
| 503 | asset_service_unavailable | Баланс вышестоящего аккаунта или критический сбой | Повторите позже или обратитесь в поддержку |
Вызовы материалов не имеют стоимости модели, но при включённом ограничении частоты модельных запросов на платформе они учитываются в нём, как и любой другой запрос /v1. Общая модель ошибок описана в разделе Ошибки и отладка, а о том, как тарифицируется генерация видео, использующая эти материалы, — в разделе Цены моделей.
Что дальше
Section titled “Что дальше”- Создание задачи генерации видео — общая структура запроса для всех видеомоделей.
- Seedance — формат запроса Seedance и роли
metadata.content. - Models — найдите ID поддерживаемой видеомодели.
- Ошибки и отладка — коды статусов и порядок диагностики.