# Volcengine Ark Private Virtual Portrait Asset Management

This document describes the complete workflow for managing Volcengine Ark private virtual portrait assets through the ModelVerse API, including asset group management and asset management.
See the [official documentation](https://www.volcengine.com/docs/82379/2333601?lang=zh).

## API Endpoints

| API | Method | Path |
| --- | --- | --- |
| Create asset group | POST | `/v1/volce-asset/groups/create` |
| List asset groups | POST | `/v1/volce-asset/groups/list` |
| Get asset group details | POST | `/v1/volce-asset/groups/get` |
| Update asset group | POST | `/v1/volce-asset/groups/update` |
| Delete asset group | POST | `/v1/volce-asset/groups/delete` |
| Create asset | POST | `/v1/volce-asset/assets/create` |
| List assets | POST | `/v1/volce-asset/assets/list` |
| Get asset details | POST | `/v1/volce-asset/assets/get` |
| Update asset | POST | `/v1/volce-asset/assets/update` |
| Delete asset | POST | `/v1/volce-asset/assets/delete` |

Authentication: `Authorization: Bearer <your-api-key>`

```bash
export ENDPOINT="https://api-us-ca.umodelverse.ai"
export MODELVERSE_API_KEY="<your-api-key>"
```

## Workflow

Virtual portrait assets are typically used in the following steps:

1. Call `POST /v1/volce-asset/groups/create` to create an asset group, with `group_type` set to `AIGC`.
2. Use the returned asset group ID as `group_id` to call the asset creation API and add image, video, or audio URLs to that asset group.
3. After confirming the asset status is `Active` via the asset query API, use the corresponding asset in model calls that support private assets.

## Asset Group Management

Asset groups are used to categorize and manage assets. Virtual portrait asset groups must be created through the API, and `group_type` must be set to `AIGC` at creation time.

### Create Asset Group

Creates a virtual portrait asset group. After a successful call, use the returned asset group ID to create assets.

**POST** `/v1/volce-asset/groups/create`

#### Request Body

```json
{
  "name": "virtual-portrait-group",
  "description": "Used for digital human generation",
  "group_type": "AIGC"
}
```

#### Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | Asset group name. |
| `description` | string | No | Asset group description. |
| `group_type` | string | Yes | Asset group type. Must be `AIGC` for virtual portrait assets. |

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/groups/create" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "virtual-portrait-group",
    "description": "Used for digital human generation",
    "group_type": "AIGC"
  }'
```

#### Response Example

```json
{
  "id": "group-20260331145705-xxxxx"
}
```

#### Response Fields

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Asset group ID. |

### List Asset Groups

**POST** `/v1/volce-asset/groups/list`

#### Request Body

```json
{
  "filter": {
    "group_ids": ["group-20260331145705-xxxxx"],
    "group_type": "AIGC",
    "name": "test"
  },
  "page_number": 1,
  "page_size": 10
}
```

#### Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filter.group_ids` | string[] | No | List of asset group IDs. When empty, queries all asset groups visible to the current account. |
| `filter.group_type` | string | No | Asset group type. Valid values: `LivenessFace`, `AIGC`. Virtual portrait assets use `AIGC`. |
| `filter.name` | string | No | Asset group name; supports fuzzy matching. |
| `page_number` | integer | No | Page number, starting from 1. Default: 1. |
| `page_size` | integer | No | Number of items per page. Default: 10, maximum: 100. |

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/groups/list" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "filter": {
      "group_type": "AIGC"
    },
    "page_number": 1,
    "page_size": 10
  }'
```

#### Response Example

```json
{
  "items": [
    {
      "id": "group-20260331145705-xxxxx",
      "name": "virtual-portrait-group",
      "description": "Used for digital human generation",
      "group_type": "AIGC",
      "project_name": "default",
      "create_time": "2026-03-31T06:57:05Z",
      "update_time": "2026-03-31T06:57:05Z"
    }
  ],
  "total_count": 1,
  "page_number": 1,
  "page_size": 10
}
```

#### Response Fields

| Field | Type | Description |
| --- | --- | --- |
| `items` | object[] | Asset group list. |
| `items[].id` | string | Asset group ID. |
| `items[].name` | string | Asset group name. |
| `items[].description` | string | Asset group description. |
| `items[].group_type` | string | Asset group type. |
| `items[].project_name` | string | Project the resource belongs to. |
| `items[].create_time` | string | Creation time. |
| `items[].update_time` | string | Update time. |
| `total_count` | integer | Total number of asset groups matching the criteria. |
| `page_number` | integer | Current page number. |
| `page_size` | integer | Number of items per page. |

### Get Asset Group Details

**POST** `/v1/volce-asset/groups/get`

#### Request Body

```json
{
  "id": "group-20260331145705-xxxxx"
}
```

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/groups/get" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "group-20260331145705-xxxxx"
  }'
```

#### Response Example

```json
{
  "id": "group-20260331145705-xxxxx",
  "name": "virtual-portrait-group",
  "description": "Used for digital human generation",
  "group_type": "AIGC",
  "project_name": "default",
  "create_time": "2026-03-31T06:57:05Z",
  "update_time": "2026-03-31T06:57:05Z"
}
```

### Update Asset Group

Updates the name or description of an asset group.

**POST** `/v1/volce-asset/groups/update`

#### Request Body

```json
{
  "id": "group-20260331145705-xxxxx",
  "name": "new-name",
  "description": "new-description"
}
```

#### Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | Asset group ID. |
| `name` | string | No | New asset group name. At least one of `name` and `description` must be provided. |
| `description` | string | No | New asset group description. At least one of `name` and `description` must be provided. |

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/groups/update" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "group-20260331145705-xxxxx",
    "name": "virtual-portrait-group",
    "description": "Used for digital human generation"
  }'
```

#### Response Example

```json
{
  "id": "group-20260331145705-xxxxx"
}
```

### Delete Asset Group

Deletes the specified asset group.

**Warning: Deleting an asset group cascades to delete all assets in the group. This operation is irreversible. Before deleting, make sure the asset group and the assets in it are no longer used by your business.**

**POST** `/v1/volce-asset/groups/delete`

#### Request Body

```json
{
  "id": "group-20260331145705-xxxxx"
}
```

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/groups/delete" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "group-20260331145705-xxxxx"
  }'
```

#### Response Example

```json
{}
```

## Asset Management

An asset represents a single item in an asset group. When creating an asset, you must provide a publicly accessible URL; Base64 upload is not supported.

### Create Asset

Creates an asset in the specified asset group. A successful call only means the asset has been submitted; the asset still goes through asynchronous processing. Use the get-asset-details or list-assets API to confirm that `status` is `Active` before using it.

**POST** `/v1/volce-asset/assets/create`

#### Request Body

```json
{
  "group_id": "group-20260331145705-xxxxx",
  "url": "https://example.com/image.jpg",
  "name": "test-image",
  "asset_type": "Image"
}
```

#### Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `group_id` | string | Yes | ID of the asset group the asset belongs to. |
| `url` | string | Yes | Publicly accessible URL of the asset. |
| `name` | string | No | Asset name. |
| `asset_type` | string | Yes | Asset type. Valid values: `Image`, `Video`, `Audio`. |

#### Asset Limits

| Type | Main limits |
| --- | --- |
| `Image` | Supports `jpeg/png/webp/bmp/tiff/gif/heic/heif`; aspect ratio `(0.4, 2.5)`; width and height `(300, 6000)` px; less than 30 MB per image. |
| `Video` | Supports `mp4/mov`; resolution `480p/720p/1080p`; duration `[2, 15]` seconds; aspect ratio `[0.4, 2.5]`; width and height `[300, 6000]` px; total pixels `[409600, 2086876]`; less than 50 MB; FPS `[24, 60]`. |
| `Audio` | Supports `wav/mp3`; duration `[2, 15]` seconds; less than 15 MB. |

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/assets/create" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "group_id": "group-20260331145705-xxxxx",
    "url": "https://example.com/image.jpg",
    "name": "test-image",
    "asset_type": "Image"
  }'
```

#### Response Example

```json
{
  "id": "Asset-20260331150000-xxxxx"
}
```

### List Assets

**POST** `/v1/volce-asset/assets/list`

#### Request Body

```json
{
  "filter": {
    "group_ids": ["group-20260331145705-xxxxx"],
    "group_type": "AIGC",
    "statuses": ["Active"],
    "name": "test"
  },
  "page_number": 1,
  "page_size": 10,
  "sort_by": "CreateTime",
  "sort_order": "Desc"
}
```

#### Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filter.group_ids` | string[] | No | List of asset group IDs. When empty, queries assets under the asset groups visible to the current account. |
| `filter.group_type` | string | No | Asset group type. Valid values: `LivenessFace`, `AIGC`. Virtual portrait assets use `AIGC`. |
| `filter.statuses` | string[] | No | List of asset statuses. Valid values: `Active`, `Processing`, `Failed`. |
| `filter.name` | string | No | Asset name; supports fuzzy matching. |
| `page_number` | integer | No | Page number, starting from 1. Default: 1. |
| `page_size` | integer | No | Number of items per page. Default: 10, maximum: 100. |
| `sort_by` | string | No | Sort field. Valid values: `CreateTime`, `UpdateTime`, `GroupId`. |
| `sort_order` | string | No | Sort direction. Valid values: `Desc`, `Asc`. |

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/assets/list" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "filter": {
      "group_ids": ["group-20260331145705-xxxxx"],
      "group_type": "AIGC",
      "statuses": ["Active"]
    },
    "page_number": 1,
    "page_size": 10
  }'
```

#### Response Example

```json
{
  "items": [
    {
      "id": "Asset-20260331150000-xxxxx",
      "name": "test-image",
      "url": "https://example.com/asset-url",
      "group_id": "group-20260331145705-xxxxx",
      "asset_type": "Image",
      "status": "Active",
      "error": {
        "code": "",
        "message": ""
      },
      "project_name": "default",
      "create_time": "2026-03-31T07:00:00Z",
      "update_time": "2026-03-31T07:00:30Z"
    }
  ],
  "total_count": 1,
  "page_number": 1,
  "page_size": 10
}
```

#### Response Fields

| Field | Type | Description |
| --- | --- | --- |
| `items` | object[] | Asset list. |
| `items[].id` | string | Asset ID. |
| `items[].name` | string | Asset name. |
| `items[].url` | string | Asset access URL. |
| `items[].group_id` | string | ID of the asset group the asset belongs to. |
| `items[].asset_type` | string | Asset type: `Image`, `Video`, `Audio`. |
| `items[].status` | string | Asset status: `Active`, `Processing`, `Failed`. |
| `items[].error.code` | string | Error code when processing fails. |
| `items[].error.message` | string | Error message when processing fails. |
| `items[].project_name` | string | Project the resource belongs to. |
| `items[].create_time` | string | Creation time. |
| `items[].update_time` | string | Update time. |
| `total_count` | integer | Total number of assets matching the criteria. |
| `page_number` | integer | Current page number. |
| `page_size` | integer | Number of items per page. |

### Get Asset Details

**POST** `/v1/volce-asset/assets/get`

#### Request Body

```json
{
  "id": "Asset-20260331150000-xxxxx"
}
```

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/assets/get" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "Asset-20260331150000-xxxxx"
  }'
```

#### Response Example

```json
{
  "id": "Asset-20260331150000-xxxxx",
  "name": "test-image",
  "url": "https://example.com/asset-url",
  "group_id": "group-20260331145705-xxxxx",
  "asset_type": "Image",
  "status": "Active",
  "error": {
    "code": "",
    "message": ""
  },
  "project_name": "default",
  "create_time": "2026-03-31T07:00:00Z",
  "update_time": "2026-03-31T07:00:30Z"
}
```

### Update Asset

Currently only the asset name can be updated.

**POST** `/v1/volce-asset/assets/update`

#### Request Body

```json
{
  "id": "Asset-20260331150000-xxxxx",
  "name": "new-name"
}
```

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/assets/update" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "Asset-20260331150000-xxxxx",
    "name": "new-name"
  }'
```

#### Response Example

```json
{
  "id": "Asset-20260331150000-xxxxx"
}
```

### Delete Asset

Deletes the specified asset.

**POST** `/v1/volce-asset/assets/delete`

#### Request Body

```json
{
  "id": "Asset-20260331150000-xxxxx"
}
```

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/assets/delete" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "id": "Asset-20260331150000-xxxxx"
  }'
```

#### Response Example

```json
{}
```

## Notes

- All APIs perform permission checks based on the account that the current API Key belongs to. You can only query and manage asset groups and assets visible to the current account.
- Virtual portrait asset groups must be created through the `groups/create` API, and `group_type` must be `AIGC`.
- When creating an asset, `url` must be a publicly accessible URL that the server can reach.
- Asset creation is processed asynchronously. After `assets/create` returns an asset ID, poll `assets/get` or `assets/list` until `status` becomes `Active`.
- Deleting an asset group cascades to delete all assets in the group, and this operation is irreversible.
- For API error codes, see [Error Code](/docs/modelverse/api_doc/common/error-code).
