# 「⚠️保密信息」【申请权限填客户名称】Assets API 参考文档（邀测用户版）

本文介绍素材资产（Assets）API 接口的参数。您可以使用以下 Assets API 接口创建、管理个人人像素材资产。

> 本文档仅限预览及邀测用户使用：
>
> * 不承诺正式 API 上线100%一致。
>
> * 仅限邀测用户阅读，请勿截图/分享给其他人员。
>
> * 您需确保上传的虚拟人像符合以下条件：
>
>   * 您合法拥有该素材，并享有完整的使用及处分权限。素材不包含未获授权的第三方商标、标识类内容。
>
>   * 素材不得与任何自然人肖像或形象雷同，素材不存在抄袭、盗用情形，不会侵害任何第三方的人格权、知识产权等合法权益。
>
>   * 素材不包含违反法规、违背公序良俗、危害国家安全的内容。



# 素材资产（Assets）API 接口功能

> **素材资产的概念说明：**
>
> * **Asset（素材资产）**：一个素材文件（图片），是方舟 Seedance 2.0 系列模型可直接用于推理的可信资产。
>
>   * 仅需入库推理需使用的素材资产，不需使用的素材资产请勿入库。
>
>   * 仅可使用已入库素材资产的 Id (Asset ID) 进行视频生成，同一形象未入库素材无法使用。
>
> * **Asset Group（素材资产组合）**：单个素材文件为一个 Asset，每个 Asset 属于一个 Asset Group。
>
>   * 可以使用素材组自由管理素材，例如可将同一人物、同一工作室或项目组的素材放入同一素材组合进行管理。

**Asset (Group) 创建接口：**

1. CreateAssetGroup：创建素材资产组合。**首次创建素材资产组合时需在控制台签署授权函，详情参考 [ 私域虚拟人像素材库 (WIP)](https://bytedance.larkoffice.com/wiki/RtHgwpJgviwFXLkQ9hLcRooEnVe)**

2. CreatAsset：创建素材资产。该接口可用于上传个人素材资产，创建素材资产后可利用返回字段中的素材 **Id （需处于 `active` 状态）**&#x7528;于 Seedance 2.0 系列模型生成视频。



**Asset (Group) 管理接口：**

* ListAssetGroups：查询素材资产组合列表。

* ListAssets：查询素材资产列表。

* GetAsset：查询素材资产信息。

* GetAssetGroup：查询素材资产组合信息。

* UpdateAssetGroup：更新素材资产组合信息。

* UpdateAsset：更新素材资产信息。



# 鉴权方式

调用素材资产（Assets）API 接口需使用 Access Key 鉴权，详情参考 [获取 API 访问密钥（AK/SK）](https://www.volcengine.com/docs/6257/64983?lang=zh)。



# 限流要求

* 并发数限制：账号下同一时刻在处理中的任务数量上限，超过此限制的任务将进入队列等待处理。**同时进行处理的asset创建任务不超过30。**

* QPS 限流： API接口每秒查询请求的总数上限。超过此限制的查询请求会报错。

| 接口名              | 账号维度的 QPS 限流 |
| ---------------- | ------------ |
| CreateAssetGroup | 30           |
| CreateAsset      | 30           |
| ListAssetGroups  | 30           |
| ListAssets       | 30           |
| GetAsset         | 100          |
| GetAssetGroup    | 100          |
| UpdateAsset      | 30           |
| UpdateAssetGroup | 30           |

# CreateAssetGroup

> **POST&#x20;**/open/CreateAssetGroup

创建 Asset Group（素材资产组合）组合，用作素材资产管理。

> **首次创建 Asset Group（素材资产组合）需在控制台签署授权函，详情参考 [ 私域虚拟人像素材库 (WIP)](https://bytedance.larkoffice.com/wiki/RtHgwpJgviwFXLkQ9hLcRooEnVe)**

### **Name** `string` `必填`

Asset Group（素材资产组合）的名称，上限为 64 字符。

***

### **Description** `string`

Asset Group（素材资产组合）的描述，上限为 300 字符。

***

### **GroupType &#x20;**`string`

Asset Group（素材资产组合）的类型。可选值：

* AIGC：虚拟人像。

***

### **ProjectName&#x20;**`string`**&#x20;**

资源所属的项目名称，默认值为`default`。

若资源不在默认项目中，需填写正确的项目名称，获取项目名称，请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。

***



## 返回参数

### **Id** `string`

Asset Group（素材资产组合）的 Id。

***

返回示例：

```bash
{
    "Id": "group-2026**********-*****"
}
```



# CreateAsset&#x20;

> **POST&#x20;**/open/CreateAsset

向指定的Asset Group（素材资产组合）内创建Asset（素材资产）。



## 请求参数

### **GroupId** `string` `必填`

Asset（素材资产）所属的 Asset Group（素材资产组合）的 Id。

***

### **URL** `string` `必填`

传入的Asset（素材资产）的公共可访问地址。

***

### **Name** `string`&#x20;

Asset（素材资产）的名称，上限为64个字符。

***

### **AssetType `string` `必填`**

Asset（素材资产）的类型，当前仅支持传入图像。可选值：

* Image：Asset（素材资产）的类型为图像。

> **传入图像的要求说明**
>
> * 格式：jpeg、png、webp、bmp、tiff、gif、heic/heif
>
> * 宽高比（宽/高）： (0.4, 2.5)&#x20;
>
> * 宽高长度（px）：(300, 6000)
>
> * 大小：单张图片小于 30 MB。

***

### **ProjectName** `string`&#x20;

资源所属的项目名称，默认值为`default`。

若资源不在默认项目中，需填写正确的项目名称，获取项目名称，请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。

> 需要和待传入的 Asset Group（素材资产组合）的 **ProjectName&#x20;**&#x4FDD;持一致。

***



## 返回参数

### **Id&#x20;**`string`&#x20;

Asset（素材资产）的 Id。

***

返回示例：

```bash
{
    "Id": "Asset-2026**********-*****"
}
```



# ListAssets

> **POST&#x20;**/open/ListAssets

查询符合筛选条件的Assets（素材资产）列表。

## 请求参数

### **Filter** `object` `必填`

搜索的过滤条件。

***

Filter.**GroupIds** `array`

Asset（素材资产）所属的 Asset Group（素材资产组合）的 Id。

***

Filter.**GroupType** `string` `必填`

Asset Group（素材资产组合）的类型。可选值：

* AIGC：虚拟人像。

***

Filter.**Statuses** `array`**&#x20;**

任务状态。

* Active：素材资产（Asset）已处理完毕，可以使用。

* Processing：素材资产（Asset）正在预处理，无法使用。

* Failed：素材资产（Asset）处理失败。

***

Filter.**Name** `string`**&#x20;**

Asset（素材资产）的名称，上限为64个字符。

***

### **PageNumber** `int (i64)` `必填`

搜索页码，可用于列表分页功能，从 1 开始。例如："page\_number": 1，即返回第一页的搜索结果。

***

### **PageSize** `int (i64)` `必填`

每页搜索结果的数量，上限为100。

***

### **SortBy** `string`

用于排序的字段名称，默认值 `createTime`。支持以下类型：

* CreateTime：根据创建时间排序。

* UpdateTime：根据更新时间排序。

* GroupId：根据资产素材组的 Id 排序。

***

### **SortOrder** `string`

排序顺序，默认值 `Desc`。可选值：

* Desc：降序

* Asc：升序

***

### **ProjectName** `string`

资源所属的项目名称，默认值为`default`。

若资源不在默认项目中，需填写正确的项目名称，获取项目名称，请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。

***



## 返回参数

### **Items** `array[]`&#x20;

符合筛选条件的Asset（素材资产）数组。

***

Items.**Id** `string`

Asset（素材资产）的 Id。

***

Items.**name** `string`

Asset（素材资产）的名称，上限为64个字符。

***

Items.**URL** `string`

Asset（素材资产）的公共可访问地址。

***

Items.**GroupId** `string`&#x20;

Asset（素材资产）所属的 Asset Group（素材资产组合）的 Id。

***

Items.**AssetType** `string`

Asset（素材资产）的类型。

* Image：Asset（素材资产）的类型为图像。

***

Items.**Status** `string`

任务状态。

* Active：素材资产（Asset）已处理完毕，可以使用。

* Processing：素材资产（Asset）正在预处理，无法使用。

* Failed：素材资产（Asset）处理失败。

***

Items.**Error** `object`

错误信息。

***

Items.Error.**Code** `string`

错误码。

***

Items.Error.**Message** `string`

错误信息。

***

Items.**ProjectName** `string`

资源所属的项目名称。

***

Items.**CreateTime&#x20;**`string`

创建时间。

***

Items.**UpdateTime&#x20;**`string`

更新时间。

***

### **TotalCount&#x20;**`int (i64)`

返回总数。

***

### **PageNumber&#x20;**`int (i64)`

返回的页数。

***

### **PageSize&#x20;**`int (i64)`

每页搜索结果的数量，上限为100。



# ListAssetGroups

> **POST&#x20;**/open/ListAssetGroups

查询符合筛选条件的Asset Groups（素材资产组合）列表。

## 请求参数

### **Filter** `object` `必填`

搜索的过滤条件。

***

Filter.**name** `string`

Asset Group（素材资产组合）的名称，上限为64个字符。

***

Filter.**GroupIds** `array`

Asset（素材资产）所属的 Asset Group（素材资产组合）的 Id。

***

Filter.**GroupType** `string`**&#x20;**`必填`

Asset Group（素材资产组合）的类型。可选值：

* AIGC：虚拟人像。

***

### **PageNumber** `int (i64)`

搜索页码，可用于列表分页功能，从 1 开始。例如："page\_number": 1，即返回第一页的搜索结果。

***

### **PageSize** `int (i64)`

每页搜索结果的数量，上限为100。

***

### **SortBy** `string`

用于排序的字段名称，默认值 `createTime`。支持以下类型：

* CreateTime：根据创建时间排序。

* UpdateTime：根据更新时间排序。

***

### **SortOrder** `string`

排序顺序，默认值 `Desc`。可选值：

* Desc：降序

* Asc：升序

***

### **ProjectName** `string`

资源所属的项目名称，默认值为`default`。

若资源不在默认项目中，需填写正确的项目名称，获取项目名称，请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。

***



## 返回参数

### **TotalCount&#x20;**`int (i64)`

返回的 Asset Group（素材资产组合）的总数。

***

### **Items** `array[]`&#x20;

符合筛选条件的 Asset Group（素材资产组合）数组。

***

Items.**Id** `string`

Asset Group（素材资产组合）的 Id。

***

Items.**Name** `string`

Asset Group（素材资产组合）的名称，上限为64个字符。

***

Items.**Title** `string`

Asset Group（素材资产组合）的标题。

> 即将下线，请直接使用参数 Name

***

Items.**Description** `string`

Asset Group（素材资产组合）的描述，上限为 300 字符。

***

Items.**GroupType** `string`

Asset Group（素材资产组合）的类型。

* AIGC：虚拟人像。

***

Items.**ProjectName** `string`

资源所属的项目名称。

***

Items.**CreateTime** `string`

创建时间。

***

Items.**UpdateTime** `string`

更新时间。

***

### **PageNumber&#x20;**`int (i64)`

返回的页数。

***

### **PageSize&#x20;**`int (i64)`

每页搜索结果的数量，上限为100。

***



# GetAssetGroup

> **POST&#x20;**/open/GetAssetGroup

获取单个Asset Group（素材资产组合）信息。

## 请求参数



### **Id&#x20;**`string` `必填`

Asset Group（素材资产组合）的 Id

***

### **ProjectName&#x20;**`string`

需要查询的 Asset Group（素材资产组合）所属的项目名称，默认值为`default`。

若资源不在默认项目中，需填写正确的项目名称，获取项目名称，请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。

***



## 返回参数

### **Id** `string`

Asset Group（素材资产组合）的 Id。

***

### **Name** `string`

Asset Group（素材资产组合）的名称，上限为64个字符。

***

### **Title** `string`&#x20;

Asset Group（素材资产组合）的标题。

> 即将下线，请直接使用参数 Name

***

### **Description** `string`

Asset Group（素材资产组合）的描述，上限为 300 字符。

***

### **GroupType &#x20;**`string`

Asset Group（素材资产组合）的类型。

* AIGC：虚拟人像

***

### **ProjectName&#x20;**`string`**&#x20;**

资源所属的项目名称。

***

### **CreateTime&#x20;**`string`

创建时间。

***

### **UpdateTime&#x20;**`string`

更新时间。

***

##

# GetAsset

> **POST&#x20;**/open/GetAsset

获取单个Asset（素材资产）信息。

## 请求参数



### **Id&#x20;**`string`  `必填`&#x20;

Asset（素材资产）的 Id。

***

### **ProjectName&#x20;**`string`

需要查询的 Asset（素材资产）所属的项目名称，默认值为`default`。

若资源不在默认项目中，需填写正确的项目名称，获取项目名称，请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。

***



## 返回参数

### **Id&#x20;**`string`

Asset（素材资产）的 Id。

***

### **Name** `string`

Asset（素材资产）的名称，上限为64个字符。

***

### **URL &#x20;**`string`

Asset（素材资产）的访问地址。

***

### **AssetType&#x20;**`string`

Asset（素材资产）的类型。

* Image：Asset（素材资产）的类型为图像。

***

### **GroupId** `string`

Asset（素材资产）所属的 Asset Group（素材资产组合）的 Id。

***

### **Status** `string`

任务状态。

* Active：素材资产（Asset）已处理完毕，可以使用。

* Processing：素材资产（Asset）正在预处理，无法使用。

* Failed：素材资产（Asset）处理失败。

***

### **Error** `object`

错误信息。

***

Error.**Code** `string`

错误码。

***

Error.**Message** `string`

错误信息。

***

### **CreateTime&#x20;**`string`

创建时间。

***

### **UpdateTime&#x20;**&#x20;`string`

更新时间。

***

### **ProjectName** `string`&#x20;

资源所属的项目名称。

***

##

# **UpdateAssetGroup**

> **POST&#x20;**/open/UpdateAssetGroup

更新单个 Asset Group（素材资产组合）信息。当前仅支持更新 Asset Group（素材资产组合）的 Name 和 Description。

## 请求参数

### **Id&#x20;**`string` `必填`

需要更新的 Asset Group（素材资产组合）的 Id

***

### **Name&#x20;**`string`&#x20;

需要更新的 Asset Group（素材资产组合）的新名称，上限为64个字符。

***

### **Description** `string`

需要更新的 Asset Group（素材资产组合）的新描述，上限为 300 字符。

***

### **ProjectName** `string`&#x20;

需要更新的 Asset Group（素材资产组合）所属的项目名称，默认值为`default`。

若资源不在默认项目中，需填写正确的项目名称，获取项目名称，请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。

***



## 返回参数

### **Id** `string`

Asset Group（素材资产组合）的 Id。

***





# **UpdateAsset**

> **POST&#x20;**/open/UpdateAsset

更新单个Asset（素材资产）信息。当前仅支持更新Asset（素材资产）的 Name。

## 请求参数

### **Id&#x20;**`string` `必填`

需要更新的 Asset（素材资产）的 Id

***

### **Name&#x20;**`string`&#x20;

需要更新的 Asset（素材资产）的新名称，上限为64个字符。

***

### **ProjectName** `string`

需要更新的 Asset（素材资产）所属的项目名称，默认值为`default`。

若资源不在默认项目中，需填写正确的项目名称，获取项目名称，请查看 [文档](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)。

***



## 返回参数

### **Id** `string`

Asset（素材资产）的 Id。

***



# 代码示例：

> **以下示例为使用 Asset API 创建素材资产并用于视频生成的使用链路：**
>
> 1. **创建素材资产组合：**&#x8C03;用 **CreateAssetGroup** 接口创建一个素材资产组合（Asset Group），用于对同一项目或人物的素材进行统一管理。首次创建时需在控制台签署授权函。
>
> 2. **上传素材资产并等待预处理完成：**&#x8C03;用 **CreateAsset** 接口上传图片素材，传入图片的公共访问URL及所属的Group ID，获得素材资产ID（Asset ID）。
>    由于上传的素材资产需经过预处理后才能使用，可轮询调用 **GetAsset** 接口查询素材状态，直至状态变为 `Active`。若状态为 `Failed` 则表示处理失败。
>
> 3. **在视频生成 API 中使用素材：**&#x5F53;素材资产状态为 `Active` 后，将素材ID按 `Asset://<Asset_Id>` 的格式拼接成URL，在视频生成API（如Seedance 2.0系列模型）的请求中，将该URL作为参考图像的 `image_url` 传入，即可使用该素材资产生成视频。
>
> **API 鉴权方式区别说明**
>
> * **Asset API：**&#x41;ccess Key 鉴权，详情参考 [获取 API 访问密钥（AK/SK）](https://www.volcengine.com/docs/6257/64983?lang=zh)。
>
> * **视频生成 API：**&#x41;PI Key 鉴权，详情参考  [管理 API Key](https://www.volcengine.com/docs/82379/1361424?lang=zh)。
>
> **素材库[项目](https://www.volcengine.com/docs/82379/1359411?lang=zh#03ec4a65)（Project）隔离说明**
>
> * 向指定的 Asset Group（素材资产组合）内创建或查询 Asset（素材资产）时，需保证两者的 **ProjectName&#x20;**&#x4E00;致
>
> * Asset（素材资产）所属的 **ProjectName** 需与调用视频生成 API 接口时使用的 API key 所属的 **ProjectName** 一致

## 1. 创建素材资产组合

```go
package main

import (
    "fmt"

    "github.com/bytedance/sonic"
    "github.com/volcengine/volcengine-go-sdk/volcengine"
    "github.com/volcengine/volcengine-go-sdk/volcengine/credentials"
    "github.com/volcengine/volcengine-go-sdk/volcengine/session"
    "github.com/volcengine/volcengine-go-sdk/volcengine/universal"
)

func main() {
    config := volcengine.NewConfig().WithCredentials(credentials.NewStaticCredentials("<your_ak>", "<your_sk>", "")).WithRegion("cn-beijing")
    sess, _ := session.NewSession(config)
    resp, err := universal.New(sess).DoCall(
        universal.RequestUniversal{
            ServiceName: "ark",
            Action:      "CreateAssetGroup",
            Version:     "2024-01-01",
            HttpMethod:  universal.POST,
            ContentType: universal.ApplicationJSON,
        },
        //根据实际情况填写
        &map[string]any{
            "Name":        "test",
            "Description": "test",
            "GroupType":   "AIGC",
        },
    )
    if err != nil {
        return
    }
    if resp == nil {
        return
    }
    respData, err := sonic.Marshal(resp)
    fmt.Println(string(respData))
}
```

返回示例

```json
{"ResponseMetadata":{"RequestId":"20260318155041036F7CB6362358FB40FC","Action":"CreateAssetGroup","Version":"2024-01-01","Service":"ark","Region":"cn-beijing"},"Result":{"Id":"group-2026**********-*****"}}
```



## 2. 上传素材资产并获取素材资产信息

```go
package main

import (
    "errors"
    "fmt"
    "time"

    "github.com/bytedance/sonic"
    "github.com/volcengine/volcengine-go-sdk/volcengine"
    "github.com/volcengine/volcengine-go-sdk/volcengine/credentials"
    "github.com/volcengine/volcengine-go-sdk/volcengine/session"
    "github.com/volcengine/volcengine-go-sdk/volcengine/universal"
)

const (
    region      = "cn-beijing"
    serviceName = "ark"
    version     = "2024-01-01"

    // 轮询配置
    pollInterval = 3 * time.Second
    pollTimeout  = 2 * time.Minute
)

func main() {
    // TODO: 替换为你的 AK / SK
    ak := "<your_ak>"
    sk := "<your_sk>"

    // TODO: 替换为你的实际参数
    groupID := "<group-20260318033332-*****>"
    assetURL := "<image_url>"
    assetType := "Image"
    projectName := "Default"

    config := volcengine.NewConfig().
        WithCredentials(credentials.NewStaticCredentials(ak, sk, "")).
        WithRegion(region)

    sess, err := session.NewSession(config)
    if err != nil {
        fmt.Printf("create session failed: %v\n", err)
        return
    }

    client := universal.New(sess)

    // 1. 创建素材资产
    assetID, err := createAsset(client, groupID, assetURL, assetType, projectName)
    if err != nil {
        fmt.Printf("create asset failed: %v\n", err)
        return
    }

    fmt.Printf("asset created, AssetId = %s\n", assetID)

    // 2. 查询素材资产状态
    finalURL, err := waitForAssetActive(client, assetID, pollInterval, pollTimeout)
    if err != nil {
        fmt.Printf("poll asset failed: %v\n", err)
        return
    }

    fmt.Printf("asset is active, URL = %s\n", finalURL)
}

// createAsset 调用 CreateAsset 并返回 AssetId
func createAsset(client *universal.Universal, groupID, url, assetType, projectName string) (string, error) {
    resp, err := client.DoCall(
        universal.RequestUniversal{
            ServiceName: serviceName,
            Action:      "CreateAsset",
            Version:     version,
            HttpMethod:  universal.POST,
            ContentType: universal.ApplicationJSON,
        },
        &map[string]any{
            "GroupId":     groupID,
            "URL":         url,
            "AssetType":   assetType,
            "ProjectName": projectName,
        },
    )
    if err != nil {
        return "", err
    }
    if resp == nil {
        return "", errors.New("create asset response is nil")
    }

    // 打印原始返回，便于排查
    respData, _ := sonic.Marshal(resp)
    fmt.Printf("CreateAsset response: %s\n", string(respData))

    assetID := extractString(resp, "Result", "Id")
    if assetID == "" {
        assetID = extractString(resp, "Result", "AssetId")
    }
    if assetID == "" {
        assetID = extractString(resp, "Id")
    }
    if assetID == "" {
        assetID = extractString(resp, "AssetId")
    }

    if assetID == "" {
        return "", fmt.Errorf("cannot find AssetId in response: %s", string(respData))
    }

    return assetID, nil
}

// waitForAssetActive 查询 GetAsset，直到 Active / Failed / 超时
func waitForAssetActive(client *universal.Universal, assetID string, interval, timeout time.Duration) (string, error) {
    deadline := time.Now().Add(timeout)

    for {
        if time.Now().After(deadline) {
            return "", fmt.Errorf("polling timeout after %v, assetID=%s", timeout, assetID)
        }

        status, url, errMsg, err := getAssetStatus(client, assetID)
        if err != nil {
            return "", err
        }

        fmt.Printf("asset status: %s\n", status)

        switch status {
        case "Processing":
            time.Sleep(interval)
            continue
        case "Active":
            if url == "" {
                return "", fmt.Errorf("asset is Active but URL is empty, assetID=%s", assetID)
            }
            return url, nil
        case "Failed":
            if errMsg == "" {
                errMsg = "unknown asset processing error"
            }
            return "", fmt.Errorf("asset processing failed: %s", errMsg)
        default:
            // 若返回其他状态，保守处理为继续查询
            fmt.Printf("unexpected status %q, continue polling...\n", status)
            time.Sleep(interval)
        }
    }
}

// getAssetStatus 调用 GetAsset，返回 Status / URL / Error
func getAssetStatus(client *universal.Universal, assetID string) (status, url, errMsg string, err error) {
    resp, err := client.DoCall(
        universal.RequestUniversal{
            ServiceName: serviceName,
            Action:      "GetAsset",
            Version:     version,
            HttpMethod:  universal.POST,
            ContentType: universal.ApplicationJSON,
        },
        &map[string]any{
            "Id": assetID,
        },
    )
    if err != nil {
        return "", "", "", err
    }
    if resp == nil {
        return "", "", "", errors.New("get asset response is nil")
    }

    // 打印原始返回，便于排查
    respData, _ := sonic.Marshal(resp)
    fmt.Printf("GetAsset response: %s\n", string(respData))

    // 兼容不同层级的字段位置
    status = extractString(resp, "Result", "Status")
    if status == "" {
        status = extractString(resp, "Status")
    }

    url = extractString(resp, "Result", "URL")
    if url == "" {
        url = extractString(resp, "URL")
    }

    errMsg = extractString(resp, "Result", "Error")
    if errMsg == "" {
        errMsg = extractString(resp, "Error")
    }

    return status, url, errMsg, nil
}

// extractString 从响应中按层级安全提取字符串
func extractString(data any, keys ...string) string {
    current := data

    for _, key := range keys {
        switch v := current.(type) {
        case map[string]any:
            next, ok := v[key]
            if !ok {
                return ""
            }
            current = next

        case *map[string]any:
            if v == nil {
                return ""
            }
            next, ok := (*v)[key]
            if !ok {
                return ""
            }
            current = next

        default:
            return ""
        }
    }

    switch v := current.(type) {
    case string:
        return v
    case fmt.Stringer:
        return v.String()
    case nil:
        return ""
    default:
        return fmt.Sprintf("%v", v)
    }
}
```

返回示例

```json
CreateAsset response: {"ResponseMetadata":{"RequestId":"202603181520431F067112A17FC078A6DF","Action":"CreateAsset","Version":"2024-01-01","Service":"ark","Region":"cn-beijing"},"Result":{"Id":"Asset-2026**********-*****"}}
asset created, AssetId = asset-20260318072044-n8bcl
GetAsset response: {"ResponseMetadata":{"Service":"ark","Region":"cn-beijing","RequestId":"202603181520448A995106924553F77D0E","Action":"GetAsset","Version":"2024-01-01"},"Result":{"Name":"","GroupId":"group-2026**********-*****","CreateTime":"2026-03-18T07:20:44Z","ProjectName":"default","Id":"Asset-2026**********-*****","URL":"","AssetType":"Image","Status":"Processing","UpdateTime":"2026-03-18T07:20:44Z"}}
asset status: Processing
GetAsset response: {"Result":{"UpdateTime":"2026-03-18T07:20:47Z","ProjectName":"default","Id":"Asset-2026**********-*****","CreateTime":"2026-03-18T07:20:44Z","Name":"","URL":"","AssetType":"Image","GroupId":"group-2026**********-*****","Status":"Processing"},"ResponseMetadata":{"Version":"2024-01-01","Service":"ark","Region":"cn-beijing","RequestId":"2026031815204766FE2BA543E6FF666F66","Action":"GetAsset"}}
asset status: Processing
GetAsset response: {"ResponseMetadata":{"Version":"2024-01-01","Service":"ark","Region":"cn-beijing","RequestId":"202603181520511F067112A17FC078A75A","Action":"GetAsset"},"Result":{"Name":"","URL":"https://ark-media-asset-stg.tos-cn-beijing.volces.com/xxxx","AssetType":"Image","Status":"Active","Id":"Asset-2026**********-*****","GroupId":"group-2026**********-*****","CreateTime":"2026-03-18T07:20:44Z","UpdateTime":"2026-03-18T07:20:47Z","ProjectName":"default"}}
asset status: Active
asset is active, URL = https://ark-media-asset-stg.tos-cn-beijing.volces.com/xxxx
```



更多语言的示例代码详见：

> 注意替换 Demo 中的 AK与SK，若需调用其他接口如 ListAssets，需替换 ACTION 与对应请求参数。

| **Python** | 创建素材资产组合： 上传素材资产并获取素材资产信息：  |
| ---------- | --------------------------- |
| **Java**   | 创建素材资产组合： 上传素材资产并获取素材资产信息：  |
| **PHP**    | 创建素材资产组合： 上传素材资产：           |



## 3. 素材资产用于视频生成

当上传的素材资产状态为 `Active` 时，可将素材 Id 按 `Asset: //<Asset_Id>` 的规则拼接 URL，以在 **视频生成 API&#x20;**&#x4E2D;使用对应的素材资产生成视频：

```json
            {
                "type": "image_url",
                "image_url": {
                    "url": "Asset://Asset-2026**********-*****"
                },
                "role": "reference_image"
            },
```

使用素材资产生成视频的具体调用方式请参考[ 【申请权限填客户名称】Seedance 2.0 & 2.0 fast API文档（邀测用户版）](https://bytedance.larkoffice.com/wiki/SANpwJ9bgiKgrykLaMTcAB0InWc#share-ONSwd51ezoXCJqxkAm2cIC61nMX)。

