Guide
Assets
Submit image assets, query review status, and query the asset list
Assets
After submission, assets are processed asynchronously by the platform; they can only be used in video tasks after the status changes from Processing to Active.
Submit Image Assets
/api/v1/materials/assetsAuthentication
Authorization: Bearer <API_KEY>.
Request Body · application/json
Prop
Type
Only one of image_url and data_url can be submitted. image_url can also be data:image/...;base64,..., which the platform treats as an inline image. When using a remote URL, the address must be an http(s):// address that the platform can download publicly (both http and https are supported), and it must not depend on cookies, Referer, a login page, or a browser session, and must remain valid while the platform processes it.
A remote image_url first goes through the platform's fast relay cache and is then mirrored by the asset library; ordinary images can usually be completed within seconds. The platform also supports inline images: you can write the value of image_url as data:image/...;base64,..., or use the separate data_url field. For images already available locally on the client, inline submission can save one additional external download.
data_url uploads the entire image as base64 (about 1.33 times the original size); use it only when the image truly cannot be provided at a public address: for example, when the image is behind an address that requires login, on an internal network, or available only as a local file. When using data_url, upload time depends on image size and caller bandwidth; the platform writes the image to short-term temporary relay storage rather than permanent platform asset storage. After the asset library finishes mirroring and the asset enters Active, previews preferentially use the preview_url returned by the asset library, and temporary files are cleaned up automatically by the relay service.
Image assets can only be submitted to virtual groups; assets in real groups are produced by the portrait QR code authorization flow.
request_id can also be submitted through the Idempotency-Key request header. When the same account submits repeatedly with the same request_id, the platform returns the same asset created on the first success and does not create the upstream asset again. When request_id is not submitted, the platform automatically generates a stable value from the account, group, title, and original image payload; retries with the same image and title can still be reused safely.
Request Example
curl -X POST "$LOCOPAL_BASE_URL/api/v1/materials/assets" \
-H "Authorization: Bearer $LOCOPAL_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<JSON
{
"group_id": "group-1789069780-5762d1",
"request_id": "brand-character-front-001",
"title": "角色正面定妆图",
"image_url": "$LOCOPAL_IMAGE_URL",
"tags": ["人物", "正面"]
}
JSONWhen using a local image, submit data_url instead:
{
"group_id": "group-1789069780-5762d1",
"request_id": "brand-character-front-001",
"title": "角色正面定妆图",
"file_name": "person.png",
"data_url": "data:image/png;base64,iVBORw0KGgo..."
}If the client prefers to keep using the image_url field, it can also submit an inline image directly:
{
"group_id": "group-1789069780-5762d1",
"request_id": "brand-character-front-001",
"title": "角色正面定妆图",
"image_url": "data:image/png;base64,iVBORw0KGgo..."
}Response Parameters
| Parameter | Type | Description |
|---|---|---|
code | integer | 0 on success |
msg | string | 图片素材已提交 on success |
data.asset_id | string | Asset ID, equal to data.asset.id |
data.asset.id | string | Asset ID; video tasks reference it with asset://<id> |
data.asset.kind | string | Asset type; image for images |
data.asset.title | string | Asset name (the final value after automatic completion) |
data.asset.request_id | string / null | Idempotent request ID used for this upload |
data.asset.platform_asset_id | string | The platform asset ID in the asset service, used for troubleshooting; in the current deployment it is usually the same as id |
data.asset.group_id | string | ID of the group it belongs to |
data.asset.status | string | Processing after acceptance |
data.asset.error_message | string / null | Reason for processing failure; normally null |
data.asset.note | string / null | Note; null when not submitted |
data.asset.tags | string[] | Tag list; usually an empty array when not submitted |
data.asset.mime_type | string / null | MIME type returned by the asset service; null when not returned |
data.asset.bytes | integer / null | Asset file size; null when not returned by the asset service |
data.asset.created_at | integer | Creation time (Unix seconds) |
data.asset.updated_at | integer | Update time (Unix seconds) |
Response Body
{
"code": 0,
"data": {
"asset_id": "asset-20260911035115-etexu",
"asset": {
"id": "asset-20260911035115-etexu",
"platform_asset_id": "asset-20260911035115-etexu",
"kind": "image",
"title": "角色正面定妆图",
"group_id": "group-1789069780-5762d1",
"status": "Processing",
"error_message": null,
"note": null,
"tags": [],
"mime_type": null,
"bytes": null,
"created_at": 1789069876,
"updated_at": 1789069876
}
},
"msg": "图片素材已提交"
}A successful submission only means the asset has been accepted; you still need to query the status before submitting a video task.
Error Responses
| HTTP | msg | Description |
|---|---|---|
400 | 缺少 group_id | No group provided |
400 | image_url 必须是可公开下载的 http(s) 地址,当前为 … | The URL scheme is not http / https, or the URL is incomplete; use a public http(s) address, or switch to data_url |
400 | image_url 与 data_url 只能提交一个 | Both fields were submitted, or neither was |
400 | data_url 必须是 data:image/...;base64,... 格式 | data_url has the wrong format |
400 | 图片数据无效或超过 20MB | The image data is empty or exceeds 20 MB |
400 | 素材名称不能为空 / 素材名称不能超过 64 个字符 | title validation failed |
401 | Invalid token | The API key is missing, wrong, or expired |
404 | 素材分组不存在或不属于当前账号 | group_id is wrong or does not belong to the current account |
404 | 素材分组不存在或不是虚拟素材分组 | An image was submitted to a real group |
502 / 503 | 素材服务暂不可用 | The asset service is abnormal; keep the request information and retry |
Query a Single Asset
/api/v1/materials/assets/{asset_id}Authentication
Authorization: Bearer <API_KEY>.
Request Parameters · path
Prop
Type
Request Example
curl "$LOCOPAL_BASE_URL/api/v1/materials/assets/asset-20260911035115-etexu" \
-H "Authorization: Bearer $LOCOPAL_API_KEY"Response Parameters
| Parameter | Type | Description |
|---|---|---|
code | integer | 0 on success |
msg | string | OK on success |
data.asset | object | Asset object; fields are the same as the submit API |
Values and handling of data.asset.status:
| Status | Meaning | Program behavior |
|---|---|---|
Processing | The asset is still being processed or reviewed | Save the asset_id, query later, and do not resubmit |
Active | The asset can be used for tasks that support this asset type | Use asset://<asset_id> in the video content |
Failed | Asset processing failed | Read error_message, fix the source image, and create a new asset |
Response Body
{
"code": 0,
"data": {
"asset": {
"id": "asset-20260911035115-etexu",
"platform_asset_id": "asset-20260911035115-etexu",
"kind": "image",
"title": "角色正面定妆图",
"group_id": "group-1789069780-5762d1",
"status": "Active",
"error_message": null,
"note": null,
"tags": [],
"mime_type": null,
"bytes": null,
"created_at": 1789069876,
"updated_at": 1789069877
}
},
"msg": "OK"
}A review failure also returns HTTP 200, with the reason in error_message:
{
"code": 0,
"data": {
"asset": {
"id": "asset-20260911035115-etexu",
"status": "Failed",
"error_message": "素材处理失败"
}
},
"msg": "OK"
}Error Responses
| HTTP | msg | Description |
|---|---|---|
401 | Invalid token | The API key is missing, wrong, or expired |
404 | 素材不存在或无权访问 | The asset ID is wrong, the asset was deleted, or it does not belong to the current account |
502 / 503 | 素材服务暂不可用 | The asset service is abnormal; keep the request information and retry |
Query the Asset List
/api/v1/materials/assetsAuthentication
Authorization: Bearer <API_KEY>.
Request Parameters · query
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 1 | Page number |
page_size | integer | No | 20 | Items per page, maximum 100 |
group_id | string | No | — | Return only assets in this group |
Request Example
curl "$LOCOPAL_BASE_URL/api/v1/materials/assets?page=1&page_size=20&group_id=group-1789069780-5762d1" \
-H "Authorization: Bearer $LOCOPAL_API_KEY"Response Parameters
| Parameter | Type | Description |
|---|---|---|
code | integer | 0 on success |
msg | string | OK on success |
data.total | integer | Total number of matching assets |
data.page / data.page_size | integer | Pagination parameters for this request |
data.assets | array | Asset list; fields are the same as the submit API |
Response Body
{
"code": 0,
"data": {
"assets": [
{
"id": "asset-20260911035115-etexu",
"platform_asset_id": "asset-20260911035115-etexu",
"kind": "image",
"title": "角色正面定妆图",
"group_id": "group-1789069780-5762d1",
"status": "Active",
"error_message": null,
"note": null,
"tags": [],
"mime_type": null,
"bytes": null,
"created_at": 1789069876,
"updated_at": 1789069877
}
],
"total": 1,
"page": 1,
"page_size": 20
},
"msg": "OK"
}Error Responses
| HTTP | msg | Description |
|---|---|---|
401 | Invalid token | The API key is missing, wrong, or expired |
404 | 素材分组不存在或无权访问 | The specified group_id does not exist or does not belong to the current account |
500 / 502 / 503 | 素材服务暂不可用 | The asset service is abnormal; keep the request information and retry |
