# Volcengine Private Portrait Asset Management

This document describes the complete workflow for managing Volcengine private portrait assets through the ModelVerse API, including liveness verification, asset group management, and asset management.

## API Endpoints

| API | Method | Path |
| --- | --- | --- |
| Create liveness verification session | GET | `/v1/volce-asset/visual-validate/sessions` |
| Query liveness verification result | POST | `/v1/volce-asset/visual-validate/result` |
| 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

Portrait assets are typically used in the following steps:

1. Call `GET /v1/volce-asset/visual-validate/sessions` to create a liveness verification session and obtain an `h5_link` and `bearer_token`.
2. Open the `h5_link` in a browser and complete the liveness verification as instructed.
3. Call `POST /v1/volce-asset/visual-validate/result` to query the verification status. When the status is `group_ready`, a `group_id` is returned.
4. Use the `group_id` to call the asset creation API to add image, video, or audio URLs to the asset group.
5. After confirming the asset status is `Active` via the asset query API, use the corresponding asset in supported model calls.

## Liveness Verification

### Create Liveness Verification Session

Creates a liveness verification session. The `h5_link` returned must be opened by a real user in a browser to complete verification.

**GET** `/v1/volce-asset/visual-validate/sessions`

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/visual-validate/sessions" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY"
```

#### Response Example

```json
{
  "bearer_token": "2b7b3f8e-0f7d-4d4c-8f0f-xxxxxxxxxxxx",
  "h5_link": "https://example.com/visual-validate?token=xxxx"
}
```

#### Response Fields

| Field | Type | Description |
| --- | --- | --- |
| `bearer_token` | string | Query credential for this verification session, used to query the verification result. Valid for approximately 30 minutes. |
| `h5_link` | string | Liveness verification H5 link. You must guide the user to open this link to complete verification. |

### Query Liveness Verification Result

After completing verification, use the `bearer_token` to query the verification status and asset group ID.

**POST** `/v1/volce-asset/visual-validate/result`

#### Request Body

```json
{
  "bearer_token": "2b7b3f8e-0f7d-4d4c-8f0f-xxxxxxxxxxxx"
}
```

#### Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `bearer_token` | string | Yes | The query credential returned when creating the verification session. |

#### Request Example

```bash
curl --location "$ENDPOINT/v1/volce-asset/visual-validate/result" \
  --header "Authorization: Bearer $MODELVERSE_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "bearer_token": "2b7b3f8e-0f7d-4d4c-8f0f-xxxxxxxxxxxx"
  }'
```

#### Response Example

```json
{
  "status": "group_ready",
  "group_id": "group-20260331145705-xxxxx"
}
```

#### Response Fields

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | Verification session status. |
| `group_id` | string | Asset group ID created after liveness verification passes. Only returned with a valid value when the asset group is ready. |

#### status Values

| Value | Meaning |
| --- | --- |
| `created` | Session created; user has not yet completed liveness verification, or callback has not been processed. |
| `group_ready` | Liveness verification passed; asset group created and ready for asset creation. |
| `failed` | Liveness verification failed. |
| `expired` | Session has expired. |

## Asset Group Management

Asset groups are used to categorize and manage assets. A `LivenessFace` type asset group is automatically created after liveness verification passes.

### List Asset Groups

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

#### Request Body

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

#### Parameters

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filter.group_ids` | string[] | No | List of asset group IDs. If empty, queries all asset groups visible to the current account. |
| `filter.group_type` | string | No | Asset group type. Options: `LivenessFace`, `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 | Items per page. Default: 10, max: 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": "LivenessFace"
    },
    "page_number": 1,
    "page_size": 10
  }'
```

#### Response Example

```json
{
  "items": [
    {
      "id": "group-20260331145705-xxxxx",
      "name": "Portrait Asset Group",
      "description": "Used for digital human generation",
      "group_type": "LivenessFace",
      "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[] | List of asset groups. |
| `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 filter. |
| `page_number` | integer | Current page number. |
| `page_size` | integer | 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": "Portrait Asset Group",
  "description": "Used for digital human generation",
  "group_type": "LivenessFace",
  "project_name": "default",
  "create_time": "2026-03-31T06:57:05Z",
  "update_time": "2026-03-31T06:57:05Z"
}
```

### Update Asset Group

Update an asset group's name or description.

**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` or `description` must be provided. |
| `description` | string | No | New asset group description. At least one of `name` or `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": "Portrait Asset Group",
    "description": "Used for digital human generation"
  }'
```

#### Response Example

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

### Delete Asset Group

Delete the specified asset group.

**Warning: Deleting an asset group will cascade-delete all assets within it. This operation is irreversible. Confirm that neither the group nor its assets are in use before deleting.**

**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 within an asset group. A publicly accessible URL is required when creating an asset. Base64 upload is not supported.

### Create Asset

Create an asset in the specified asset group. A successful call only means the asset has been submitted — it still goes through asynchronous processing. Query the asset details or asset list to confirm the `status` is `Active` before use.

**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 | The asset group ID this asset belongs to. |
| `url` | string | Yes | Publicly accessible URL of the asset. |
| `name` | string | No | Asset name. |
| `asset_type` | string | Yes | Asset type. Options: `Image`, `Video`, `Audio`. |

#### Asset Constraints

| Type | Key Constraints |
| --- | --- |
| `Image` | Supports `jpeg/png/webp/bmp/tiff/gif/heic/heif`; aspect ratio `(0.4, 2.5)`; dimensions `(300, 6000)` px; single file < 30 MB. |
| `Video` | Supports `mp4/mov`; resolution `480p/720p/1080p`; duration `[2, 15]` seconds; aspect ratio `[0.4, 2.5]`; dimensions `[300, 6000]` px; total pixels `[409600, 2086876]`; < 50 MB; FPS `[24, 60]`. |
| `Audio` | Supports `wav/mp3`; duration `[2, 15]` seconds; < 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": "LivenessFace",
    "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. If empty, queries assets under all groups visible to the current account. |
| `filter.group_type` | string | No | Asset group type. Options: `LivenessFace`, `AIGC`. Default: `LivenessFace`. |
| `filter.statuses` | string[] | No | Asset status list. Options: `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 | Items per page. Default: 10, max: 100. |
| `sort_by` | string | No | Sort field. Options: `CreateTime`, `UpdateTime`, `GroupId`. |
| `sort_order` | string | No | Sort direction. Options: `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"],
      "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[] | List of assets. |
| `items[].id` | string | Asset ID. |
| `items[].name` | string | Asset name. |
| `items[].url` | string | Asset access URL. |
| `items[].group_id` | string | Asset group ID this 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 failed. |
| `items[].error.message` | string | Error message when processing failed. |
| `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 filter. |
| `page_number` | integer | Current page number. |
| `page_size` | integer | 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 supports updating the asset name.

**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

Delete 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 enforce permission checks based on the account associated with the current API Key. You can only query and manage asset groups and assets visible to the current account.
- When creating an asset, `url` must be a publicly accessible URL reachable by the server.
- Asset creation is asynchronous. After `assets/create` returns an asset ID, poll `assets/get` or `assets/list` until `status` becomes `Active`.
- Deleting an asset group will cascade-delete all assets within it. This operation is irreversible.
- For error codes, refer to [Error Codes](/docs/modelverse/modelverse/modelverse/error-code).
