Aller au contenu

Assets

L’API assets stocke le matériel de référence — images, vidéos, audio — que les modèles vidéo Seedance peuvent accepter en entrée. Vous ajoutez le matériel une fois, attendez que le service d’assets amont le traite, puis vous le référencez sous forme asset://<asset_id> dans une requête de génération vidéo plutôt que de renvoyer la même URL publique à chaque fois.

Il s’agit d’une API de gestion, pas d’une API de génération. RouteAPI authentifie l’appel avec votre clé API, le transmet au service d’assets amont et renvoie la réponse de l’amont. Les appels sur ces points de terminaison ne sont pas facturés comme un usage de modèle. Ils sont également hors du périmètre du SDK OpenAI : utilisez du HTTP simple plutôt qu’un client SDK.

  1. Créez un groupe d’assets avec POST /v1/asset-groups.
  2. Ajoutez un asset à ce groupe avec POST /v1/assets, en indiquant une URL téléchargeable publiquement.
  3. Interrogez l’asset avec GET /v1/assets/{assetID} jusqu’à ce que son statut soit Active. Le traitement est asynchrone.
  4. Référencez l’asset sous forme asset://<asset_id> dans le metadata.content d’une requête POST /v1/video/generations. Voir Utiliser un asset dans une requête Seedance et Seedance.
  5. Interrogez la tâche vidéo comme d’habitude. Les requêtes vidéo adossées à un asset sont envoyées une seule fois à l’amont ; elles ne font l’objet ni de nouvelle tentative ni de bascule vers un autre canal.
MéthodeCheminRôleAlloue de l’espace d’assets
POST/v1/asset-groupsCréer un groupe d’assetsOui
GET/v1/asset-groupsLister les groupesNon
GET/v1/asset-groups/{groupID}Obtenir un groupeNon
DELETE/v1/asset-groups/{groupID}Supprimer un groupeNon
PUT/v1/asset-groups/{groupID}Renommer un groupeNon
POST/v1/assetsAjouter un asset à un groupeOui
GET/v1/assetsLister les assets d’un groupeNon
GET/v1/assets/{assetID}Obtenir un asset (à utiliser pour l’interrogation)Non
DELETE/v1/assets/{assetID}Supprimer un assetNon
PUT/v1/assets/{assetID}Renommer un assetNon
POST/v1/assets/verify-sessionsCréer une session de vérification humaineOui
GET/v1/assets/verify-sessions/{sessionID}Obtenir une session de vérificationNon

Envoyez une clé API de modèles dans l’en-tête standard :

Authorization: Bearer sk-your-routeapi-key

La clé identifie le compte RouteAPI. Les assets sont isolés par compte : toutes les clés API d’un même compte voient les mêmes groupes, assets et sessions de vérification, et aucun autre compte ne peut les voir. La clé n’est jamais envoyée en amont — RouteAPI utilise un identifiant d’accès amont distinct pour votre compte.

Chaque compte est lié à un identifiant amont unique, que le service d’assets utilise pour isoler le matériel de ce compte. Il est attribué automatiquement la première fois que le compte appelle un point de terminaison de création :

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

Une fois attribuée, la liaison est définitive pour le compte et est réutilisée par tous les appels ultérieurs, y compris les requêtes vidéo qui référencent des assets asset://.

Les points de terminaison de lecture et de suppression n’allouent jamais. Tant que la liaison n’existe pas :

AppelRéponse
GET /v1/asset-groups200, liste vide : {"total": 0, "asset_groups": []}
Tout autre GET ou DELETE404, {"error": "not found"}

Autrement dit, une liste de groupes vide est une réponse normale pour un nouveau compte, tandis qu’un 404 sur un asset ou un groupe précis avant la première utilisation signifie « ce compte n’a pas encore d’espace d’assets », et non « l’ID est faux ».

Le routage groupe → identifiant amont relève de la configuration du service. Si votre groupe n’a aucun canal d’assets configuré, le premier appel de création échoue avec 503 asset_pool_exhausted ou 503 asset_pool_misconfigured au lieu d’allouer. Réessayez plus tard, ou contactez le support si le problème persiste.

POST /v1/asset-groups
Fenêtre de terminal
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"
}'
ChampTypeRequisDescription
namestringOuiNom du groupe
descriptionstringNonDescription du groupe

Réponse :

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

Conservez asset_group_id : il est requis pour ajouter des assets.

GET /v1/asset-groups
Fenêtre de terminal
curl "https://api.routeapi.ai/v1/asset-groups?page=1&page_size=20" \
-H "Authorization: Bearer $ROUTEAPI_KEY"

Les paramètres de pagination comme page et page_size sont transmis tels quels ; les valeurs par défaut et la taille de page maximale du service amont s’appliquent.

{
"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 n’est renseigné que pour les groupes créés via la vérification humaine. Un groupe de personne vérifiée a group_type LivenessFace ; les groupes ordinaires sont AIGC.

Fenêtre de terminal
curl https://api.routeapi.ai/v1/asset-groups/local_group_2c8186e6d8b44ffa73b371677bfe4af2 \
-H "Authorization: Bearer $ROUTEAPI_KEY"

La réponse détaillée de l’amont peut renvoyer une chaîne status vide. Utilisez la valeur de la réponse de liste ou de la réponse de création lorsque vous devez déterminer si un groupe est utilisable.

Fenêtre de terminal
curl -X DELETE https://api.routeapi.ai/v1/asset-groups/local_group_2c8186e6d8b44ffa73b371677bfe4af2 \
-H "Authorization: Bearer $ROUTEAPI_KEY"
{ "deleted": "local_group_2c8186e6d8b44ffa73b371677bfe4af2" }

La suppression est définitive.

Fenêtre de terminal
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

Un asset par requête. Indiquez le groupe, un nom et exactement une URL source.

ChampTypeRequisDescription
asset_group_idstringOuiGroupe auquel appartient l’asset
asset_namestringOuiNom utilisé uniquement pour la recherche ; il n’influence pas la génération
image_urlstringUn des troisURL publique d’une image
video_urlstringUn des troisURL publique d’une vidéo
audio_urlstringUn des troisURL publique d’un fichier audio
asset_typestringNonImage, Video ou Audio ; déduit du champ URL lorsqu’il est omis
descriptionstringNonDescription de l’asset

Indiquez exactement un champ parmi image_url, video_url et audio_url ; le service amont rejette les requêtes qui en contiennent zéro ou plusieurs. L’URL doit être téléchargeable depuis l’internet public, sans authentification ni en-têtes supplémentaires. Les charges utiles Base64 et les adresses internes ne sont pas prises en charge, et l’URL doit rester accessible jusqu’à la fin du traitement.

Fenêtre de terminal
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"
}

Une création réussie signifie que la requête a été acceptée, pas que l’asset est utilisable. asset_uri est la forme à utiliser dans les requêtes vidéo.

StatutSignificationQue faire
ProcessingIngestion en coursContinuer l’interrogation
ActivePrêt à l’emploiLe référencer dans une requête vidéo
FailedÉchec de l’ingestionVérifiez les exigences de format et de taille, puis ajoutez-le à nouveau

Utilisez ce point de terminaison pour l’interrogation, toutes les 5 à 10 secondes, avec un délai d’expiration global. Le traitement prend généralement de quelques secondes à quelques dizaines de secondes ; les assets vidéo et les périodes de forte charge prennent plus de temps.

Fenêtre de terminal
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 est une adresse de téléchargement signée temporaire. Ne la stockez pas ; utilisez asset_uri pour la génération.

Un asset absent ou supprimé renvoie 404 de la part du service amont, par exemple :

{ "details": "record not found", "error": "asset not found in database" }
Fenêtre de terminal
# 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" }

Supprimer un asset casse toute nouvelle requête vidéo qui le référence.

Fenêtre de terminal
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" }

Après le renommage, les réponses de détail et de liste de l’asset renvoient le nouveau nom.

Un matériel de référence contenant le visage d’une personne réelle nécessite d’abord le consentement de cette personne. Une session de vérification génère un groupe dédié au matériel de cette personne ; les assets qui y sont ajoutés font l’objet d’une vérification de cohérence du visage.

POST /v1/assets/verify-sessions

Le corps peut être vide ({} ou aucun corps du tout). callback_url est accepté mais n’est pas utilisé pour la redirection.

Fenêtre de terminal
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": ""
}

N’envoyez h5_link qu’à la personne qui sera vérifiée. Il contient un identifiant à usage unique et donne accès à la page de vérification ; ne le placez pas dans des journaux publics, des captures d’écran ou des discussions de groupe.

Fenêtre de terminal
curl https://api.routeapi.ai/v1/assets/verify-sessions/asset_sess_5e7860e76613dd51a4867bdcbea6076b \
-H "Authorization: Bearer $ROUTEAPI_KEY"
statusSignification
pendingEn attente de la personne, ou traitement en cours
succeededVérifiée ; asset_group_id est renseigné
failedÉchec de la vérification ; lisez 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
}

Il n’y a ni webhook ni redirection vers votre service — le navigateur de la personne se termine sur une page de résultat appartenant à l’amont. Interrogez la session jusqu’à ce que status passe à succeeded (généralement en quelques minutes), puis ajoutez le matériel de cette personne au asset_group_id renvoyé. result_code est actuellement toujours vide ; utilisez status. Une session failed avec un error tel que verification expired doit être recréée.

Référencez l’asset dans le metadata.content d’une requête de génération vidéo, en utilisant l’asset_uri renvoyé par l’API assets :

Fenêtre de terminal
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"
}
}'

Utilisez un ID de modèle Seedance issu de GET /v1/models qui prend en charge la génération vidéo ; voir Modèles. Le format de requête pour Seedance, y compris les rôles de metadata.content et les limites propres à chaque modèle, est documenté dans Seedance.

Règles issues du contrat du service d’assets :

  • Le couple type/role doit correspondre au type d’asset : image_url avec reference_image, video_url avec reference_video, audio_url avec reference_audio.
  • Seuls les assets Active peuvent être référencés.
  • Le texte du prompt désigne le matériel par son ordinal (« image 1 », « video 1 »), compté par type dans l’ordre de content. N’indiquez pas d’ID d’asset dans le prompt.
  • Le matériel d’une personne réelle doit provenir d’un groupe vérifié ; sinon l’amont peut rejeter la requête ou faire échouer la tâche.

RouteAPI détecte une référence en recherchant toute valeur de chaîne JSON commençant par asset:// (sans distinction de casse). Une telle requête est épinglée sur votre canal d’assets et envoyée une seule fois, sans nouvelle tentative ni bascule de canal. La requête est rejetée localement dans ces cas :

StatutCodeCause
400asset_key_requiredLe corps référence asset://, mais le compte n’a pas encore d’espace d’assets. Créez d’abord un groupe et un asset
400asset_remix_conflictUn remix d’une tâche non-asset tente de référencer un asset asset://
400asset_channel_conflictLa clé API est épinglée sur un canal spécifique qui n’est pas votre canal d’assets
400asset_model_unsupportedLe modèle n’est pas pris en charge par votre canal d’assets
503asset_key_unavailableL’identifiant amont lié au compte est en défaut ou désactivé

Ces erreurs utilisent la forme d’erreur de tâche {"code": ..., "message": ..., "data": ...}.

  • Corps de requête — les corps POST et PUT sont lus avec une limite de 1 MiB. Un corps plus volumineux renvoie 413 avant tout envoi en amont. Le matériel lui-même n’est jamais téléversé via le corps ; indiquez une URL.
  • Forme du corps — un corps POST ou PUT non vide doit être un objet JSON. Les tableaux, chaînes nues, null et JSON invalides renvoient 400 sans atteindre le service amont. Les corps GET et DELETE sont ignorés.
  • Corps de renommage — un corps PUT doit contenir un champ chaîne non vide name (clé en minuscules). Un name absent, vide ou non textuel renvoie 400 sans atteindre le service amont.
  • Corps de réponse — les réponses amont de plus de 10 MiB, ou les réponses qui ne peuvent pas être lues, renvoient 502.
  • Délai d’expiration — l’appel amont a un délai fixe de 60 secondes ; son expiration est signalée comme 502.
  • project_name — s’il figure dans un corps POST ou PUT, ce champ est retiré avant transmission, quelle que soit la casse.
  • Erreurs de propriété — si l’amont répond 403 avec un refus de propriété (“you do not own” / “access denied”), RouteAPI renvoie à la place 404 {"error": "not found"}, afin que la ressource semble inexistante plutôt qu’interdite.
  • Défaillances de l’identifiant amont — un 401 amont devient 503 asset_key_unavailable et marque la liaison du compte comme défaillante (voir ci-dessus). Un 402 amont, ou une erreur amont dont le corps évoque un problème de facturation, devient 503 asset_service_unavailable.

Les autres codes d’état et corps amont sont transmis inchangés, y compris les erreurs de validation de l’amont. Les erreurs propres à RouteAPI utilisent l’une des trois formes suivantes :

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

La troisième forme provient du middleware partagé d’authentification et de limitation de débit : vérifiez donc si error est une chaîne ou un objet. Le texte local de message est actuellement en chinois — pour les deux premières formes, branchez sur le statut HTTP et le champ code plutôt que sur le message.

StatutCodeSignificationTraitement
400—Le corps n’est pas un objet JSON, ou l’amont a rejeté les paramètresCorrigez la requête ; ne réessayez pas à l’identique
401—Clé API absente, invalide ou suppriméeVérifiez Authorization
404—Asset, groupe ou session inconnu ; ou aucun espace d’assets encore pour ce compteVérifiez l’ID ; créez d’abord un groupe si le compte est nouveau
413—Le corps de requête dépasse 1 MiBEnvoyez une URL au lieu de données inline
429—Limitation déclenchéeRalentissez l’interrogation et réessayez plus tard
500asset_pool_internal_errorRouteAPI n’a pas pu lire ou écrire son propre état d’assetsRéessayez plus tard
500—RouteAPI a échoué lors de la lecture de l’état d’assets du compteRéessayez plus tard
502—Amont inaccessible, expiré, ou réponse illisible ou trop volumineuseRéessayez plus tard
503asset_key_unavailableL’identifiant amont du compte est en défaut ou désactivéContactez le support ; réessayer n’aidera pas
503asset_pool_exhaustedVotre groupe n’a aucun canal d’assets, ou aucun identifiant n’est disponible pour l’allocationRéessayez plus tard ou contactez le support
503asset_pool_busyDes identifiants existent mais aucun n’a pu être alloué pour l’instantRéessayez plus tard
503asset_pool_misconfiguredVotre groupe est mappé sur plus d’un canal d’assetsContactez le support
503asset_channel_unavailableLe canal d’assets lui-même est désactivé ou mal configuréRéessayez plus tard ou contactez le support
503asset_service_unavailableSolde du compte amont ou défaillance majeureRéessayez plus tard ou contactez le support

Les appels d’assets n’ont aucun coût de modèle, mais lorsque la limitation de débit des requêtes de modèles de la plateforme est activée, ils y sont comptés comme toute autre requête /v1. Voir Erreurs et débogage pour le modèle général d’erreur, et Tarification des modèles pour savoir comment la génération vidéo qui consomme ces assets est facturée.