Skip to content
Documentation/OPEN API

Asset management

Upload synchronously or asynchronously, query tasks, download, modify, and retrieve assets.

Last updated

Upload assets

For large files, use asynchronous uploads below and query the task for its result.

Endpoint: /upload-assets

Method: POST

Description: Upload assets to the DAM system.

Request parameters:

ParameterTypeRequiredDescription
-List<EnterpriseAssetSaveReq>YesAsset save requests

This section describes uploading from a downloadable URL. The parameters below apply to this integration method.

EnterpriseAssetSaveReq fields:

FieldTypeRequiredDescription
folderIdsList<Long>NoTarget folder IDs. If empty, global upload permission such as upload to all assets is required. Otherwise, upload permission is required for every folder
nameStringNoDisplay filename; if omitted, the server attempts to infer it from the url path
urlStringYesDirectly downloadable asset URL (GET returns 200). The server downloads the file and stores it under a new key. Avoid short links blocked by hotlink protection or regional restrictions
extensionStringYesFile extension, such as jpg or mp4, matching the resource type
sizeLongNoDeclared size in bytes. The stored file size takes precedence after upload. Use the local size to assist validation
widthIntegerNoImage or video cover width in pixels. For images, the server attempts to read it from the downloaded file when omitted
heightIntegerNoImage or video cover height in pixels. For images, the server attempts to read it from the downloaded file when omitted
durationLongNoVideo duration in milliseconds
linkStringNoAssociated webpage or source link
descriptionStringNoNotes
ratingIntegerNoRating; written to the asset rating field, corresponding to internal score
userIdLongNoAsset owner user ID; defaults to the creator (the API key user). A specified user must belong to the current team
oldAssetIdLongNoOriginal asset ID (>0) when uploading a new version; used for cover/version association
metadatasList<MetadataDTO>NoCustom metadata; only effective when enabled for the team. fieldId must match an ID from the metadata fields endpoint. Field validity is checked
skipDuplicateByEtagBooleanNoSkip duplicates. When true, the server checks the team's OSS ETags after downloading to the asset bucket but before adding to the library. Existing identical content is not added again; returned id, key, and accessUrl refer to the existing asset. Defaults to false
licenseAgreementIdsList<Long>NoLinked license agreement IDs; only effective when copyright management is enabled, otherwise ignored
startTimeDateNoAsset validity start; only effective when copyright management is disabled, otherwise ignored
endTimeDateNoAsset validity end; only effective when copyright management is disabled, otherwise ignored
isPermanentBooleanNoWhether the asset is permanently valid; only effective when copyright management is disabled, otherwise ignored

Upload requests use startTime / endTime to set asset validity; search and batch retrieval return validStartTime / validEndTime. With copyright management enabled, link agreements using licenseAgreementIds; validity comes from the agreement scopes.

MetadataDTO (metadatas item):

FieldTypeRequiredDescription
fieldIdStringConditionalMetadata field ID used during upload, matching the fields endpoint; paired with value
valueObjectNoField value; type must match the field definition

Response fields:

ParameterTypeDescription
assetsList<Item>Successfully saved assets

Item fields:

FieldTypeDescription
idLongAsset ID
keyStringFile URL, OSS key, or downloadable file
storePathStringAsset OSS storage path; same as key
skippedDuplicateByEtagBooleantrue when an existing team asset is reused after an ETag match; id, key, and accessUrl refer to that asset
nameStringTitle
accessUrlStringAccess URL
uploadResultStringNEW: newly uploaded and added to the library. DUPLICATE_BY_ETAG: duplicate found; no new asset added

Example:

Request example:

bash
curl --location --request POST 'https://open.musedam.ai/api/muse/upload-assets' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '[
{
"folderIds": [
23015
],
"url": "https://example.com/assets/sample.jpg",
"name": "Sample image",
"extension": "jpeg"
}
]'

Response example:

json
{
"code": "0",
"message": "OK",
"result": {
"assets": [
{
"id": 6908936,
"key": "api_b9648d4570d2e08364a451b1eec88eea.jpeg",
"storePath": "api_b9648d4570d2e08364a451b1eec88eea.jpeg",
"uploadResult": "NEW",
"skippedDuplicateByEtag": false,
"name": "Sample image",
"accessUrl": "https://example.com/assets/sample.jpg"
}
]
}}

Upload assets asynchronously

Endpoint: /upload-assets-async

Method: POST

Upload assets from downloadable URLs asynchronously. The endpoint returns task IDs immediately while downloading and ingestion run in the background. Use this endpoint for files over 20 MB to avoid synchronous download timeouts. A successful submission returns a task ID; query the task to confirm that the asset was uploaded successfully.

Request parameters

A JSON array containing 1–50 items. Each item uses the public EnterpriseAssetSaveReq fields and permission requirements in Upload assets. Every item must have a directly downloadable url. If any item has no url, the request fails with 30313.

FieldTypeRequiredDescription
callbackUrlStringNoOptional HTTP or HTTPS callback URL, used only for asynchronous uploads. The server POSTs the task result once when the task reaches SUCCESS or FAILED

Task reuse and retries

  • Tasks are reused for the same team, API Key user, and exact url string. The asset owner userId does not participate in task reuse.
  • If the task is running or already successful, the original taskId is returned without downloading or ingesting again. Folders, name, and metadata remain as submitted the first time.
  • If the previous attempt failed, submitting the same URL reuses the original taskId and restarts the task with the new request parameters.
  • Changing a signature or expiry parameter in the URL creates a different URL and therefore a new task.

Response parameters

FieldTypeDescription
tasksList<Item>One task entry for each submitted URL
tasks[].taskIdString32-character UUID without hyphens; use this to query the task, not as an asset ID
tasks[].urlStringThe submitted URL string

Request example

bash
curl --request POST 'https://open.musedam.ai/api/muse/upload-assets-async' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '[
{
"folderIds": [
23015
],
"url": "https://example.com/assets/sample.mp4",
"name": "Product video",
"extension": "mp4",
"callbackUrl": "https://example.com/webhooks/musedam-upload"
}
]'

Response example

json
{
"code": "0",
"message": "success",
"result": {
"tasks": [
{
"taskId": "a1b2c3d4e5f64789a0b1c2d3e4f56789",
"url": "https://example.com/assets/sample.mp4"
}
]
}
}

Callbacks

Callbacks use Content-Type: application/json. The body is the query endpoint’s result object directly, without the outer code, message, or result wrapper. Success includes asset information; failure includes stage: FAILED and failReason. Callback failure does not change the task status. Only one callback attempt is made; keep task polling as a fallback.

json
{
"taskId": "a1b2c3d4e5f64789a0b1c2d3e4f56789",
"stage": "SUCCESS",
"progress": 100,
"transferredBytes": 52428800,
"totalBytes": 52428800,
"failReason": null,
"materialId": 6908936,
"storePath": "api_example.mp4",
"name": "Product video",
"accessUrl": "https://example.com/assets/sample.mp4"
}

Query an async upload task

Endpoint: /upload-assets-task

Method: POST

Query a task by taskId. It must belong to the current team and API Key user. A missing task or an ownership mismatch returns 30312.

Request parameters

FieldTypeRequiredDescription
taskIdStringYes32-character UUID without hyphens; use this to query the task, not as an asset ID

Response parameters

FieldTypeDescription
taskIdStringPublic task ID
stageStringCurrent stage; see the table below
progressInteger0–100: downloading up to 80, saving 85, ingesting 95, success 100; downloading stays at 0 when the total size is unknown
transferredBytesLongBytes downloaded from the URL
totalBytesLongContent-Length from the source URL response; null if unavailable
failReasonStringFailure reason; empty during processing or after success
materialIdLongAsset ID after success
storePathStringStorage key after success
nameStringAsset name after success
accessUrlStringReturned only for SUCCESS; re-signed on every query and valid for 1 day

Task stages

StageMeaning
WAITINGWaiting to be processed
DOWNLOADINGDownloading from the URL
SAVINGWriting to file storage
INGESTINGIngesting the asset
SUCCESSUpload complete; the returned asset information is ready to use
FAILEDUpload failed; check failReason, correct the cause, then resubmit

Poll until stage becomes SUCCESS or FAILED. progress represents overall processing progress. When the source file size is unknown, download progress stays at 0; use transferredBytes to track downloaded bytes instead of treating 0 as a stalled task.

Request example

bash
curl --request POST 'https://open.musedam.ai/api/muse/upload-assets-task' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"taskId": "a1b2c3d4e5f64789a0b1c2d3e4f56789"
}'

Response example

json
{
"code": "0",
"message": "success",
"result": {
"taskId": "a1b2c3d4e5f64789a0b1c2d3e4f56789",
"stage": "SUCCESS",
"progress": 100,
"transferredBytes": 52428800,
"totalBytes": 52428800,
"failReason": null,
"materialId": 6908936,
"storePath": "api_example.mp4",
"name": "Product video",
"accessUrl": "https://example.com/assets/sample.mp4"
}
}

Download assets

Asset downloads do not require a separate endpoint. Obtain a download link in either of these ways:

  1. Search assets: each asset returned by /search-assets includes a downloadUrl field.
  2. Retrieve assets in bulk: the batch asset retrieval response also includes download links.

Use downloadUrl directly to download the asset. Links generally contain the required authentication and access information and can be opened in a browser or used with a download tool.

Notes:

  • Download links may expire after 10 hours. Use them promptly.
  • Ensure a stable connection when downloading large files.
  • For batch downloads, consider server-side scripts to reduce client download failures.

Your team must have the Asset Derivatives / Public Links add-on enabled. Otherwise, both requests return a module-not-enabled error. These endpoints apply only to original files and do not check folder-level public link settings or roles.

FieldTypeRequiredDescription
assetIdsList<Long>YesUp to 200 materialId values returned by asset search or upload.

POST /public-links-get

Reads existing links without creating them. The business result is an object keyed by materialId. Each value is the original public URL without image processing parameters, or "" if the asset does not exist or has no public link.

bash
curl --request POST 'https://open.musedam.ai/api/muse/public-links-get' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{"assetIds": [1234567890, 9876543210]}'

Example business result

json
{
"1234567890": "https://cdn.example.com/assets/photo.jpg",
"9876543210": ""
}

POST /public-links-generate

Publishes a public link for each original file. Repeated requests return the same existing link. The result has the same shape as the query response. A missing asset or a per-asset generation failure returns "" for that ID; other assets in the batch are still processed.

bash
curl --request POST 'https://open.musedam.ai/api/muse/public-links-generate' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{"assetIds": [1234567890, 9876543210]}'

For resized or reformatted images, use processed-public-links. For public links to derivative versions, use asset-derivative-versions. See Analysis & delivery.

Modify assets

Endpoint: /modify-assets

Method: POST

Description: Update basic asset information such as name, description, and rating.

Request parameters:

ParameterTypeRequiredDescription
-AssetModifyReqYesAsset modification request

AssetModifyReq fields:

FieldTypeRequiredDescription
idLongYesAsset ID
nameStringNoFilename
descriptionStringNoDescription
scoreIntegerNoRating (1–5)
linkStringNoWebpage link
tagsList<Long>NoTag IDs

Response fields:

ParameterTypeDescription
-MiniDamAssetDTOUpdated asset information

MiniDamAssetDTO fields:

See MiniDamAssetDTO fields in asset search

Example:

Request example:

bash
curl --location --request POST 'https://open.musedam.ai/api/muse/modify-assets' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"id":6908914,
"name":"bottomTip45",
"description":"description 451",
"score":5,
"link":"wwww.baidu.com"
}'

Response example:

json
{
"code": "0",
"message": "OK",
"result": {
"id": 6908914,
"parentIds": [],
"userId": "1673603133161799680",
"name": "bottomTip45",
"downloadUrl": "https://example.com/assets/sample.jpg",
"source": null,
"link": "wwww.baidu.com",
"extension": "png",
"duration": null,
"size": 111948,
"width": 290,
"height": 220,
"description": "description 451",
"score": 5,
"createTime": 1753428273000,
"createUser": "1673603133161799680",
"updateTime": 1753942888000,
"updateUser": 367024606,
"tags": [],
"thumbnailAccessUrl": "https://example.com/assets/sample.jpg"
},
"traceId": "17539429013299310816"
}

Move assets to a folder

Endpoint: /move-assets-to-folder

Method: POST

Description: Move or add a batch of assets from a source folder to a target folder.

Request parameters:

FieldTypeRequiredDescription
assetIdsList<Long>YesAsset IDs; maximum 200 per request
fromFolderIdLongConditionalRequired and >0 when operationType=0 (move). The current folder association to remove
toFolderIdLongYesTarget folder ID (>0)
operationTypeIntegerNo0: move (remove from fromFolderId and add to toFolderId); 1: add (keep source association). Defaults to 0

Response: Boolean

Example request (move):

bash
curl --location --request POST 'https://open.musedam.ai/api/muse/move-assets-to-folder' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"assetIds": [6908914, 6908820],
"fromFolderId": 10001,
"toFolderId": 10002,
"operationType": 0
}'

Notes:

  • Assets and folders must exist and belong to the current team. Edit permission for the relevant folders is required.
  • operationType=0 moves assets; =1 adds them while keeping them in both folders.

Delete assets in bulk

POST /delete-assets moves the specified assets to the recycle bin. It cannot delete folders. The Open API does not support permanent deletion or restoring assets from the recycle bin.

Permissions: Requires an administrator API key or appKey. On the Enterprise plan, the key must be bound to the system administrator role. Member keys and user login sessions cannot call this endpoint. It does not check individual folder or asset permissions. Rate limit: 5 QPS.

Request fieldTypeRequiredDescription
assetIdsList<Long>YesSupply 1–200 asset materialId values returned by asset search or upload.

Response: The business result is a Boolean: true on success. Failures return an Open API or business error.

Request example:

bash
curl --request POST 'https://open.musedam.ai/api/muse/delete-assets' \
--header 'Authorization: Bearer your_admin_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{"assetIds": [6908914, 6908820]}'

Retrieve assets in bulk

Endpoint: /assets-by-ids

Method: POST

Description: Retrieve asset details for a list of asset IDs.

Request parameters:

ParameterTypeRequiredDescription
-List<Long>YesAsset IDs

Response fields:

ParameterTypeDescription
-List<MiniDamAssetDTO>Asset information

MiniDamAssetDTO fields:

See MiniDamAssetDTO fields in asset search

Each returned MiniDamAssetDTO also includes externalApp (external application identifier) and externalResourceRef (external resource reference). For an IngenOps canvas these are ingenops and its corresponding workspace_ref; both are null when the asset has no external association.

Example:

Request example:

bash
curl --location --request POST 'https://open.musedam.ai/api/muse/assets-by-ids' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '[6908914,6908820]'

Response example:

json
{
"code": "0",
"message": "OK",
"result": [
{
"id": 6908914,
"parentIds": [
28566
],
"userId": "1673603133161799680",
"name": "bottomTip45",
"downloadUrl": "https://example.com/assets/sample.jpg",
"source": null,
"link": "wwww.baidu.com",
"extension": "png",
"duration": null,
"size": 111948,
"width": 290,
"height": 220,
"description": "description 451",
"score": 5,
"createTime": 1753428273000,
"createUser": "1673603133161799680",
"updateTime": 1753942901660,
"updateUser": 367024606,
"tags": [],
"thumbnailAccessUrl": "https://example.com/assets/sample.jpg"
},
{
"id": 6908820,
"parentIds": [],
"userId": "1673603133161799680",
"name": "Full-Stack-Serverless",
"downloadUrl": "https://example.com/assets/sample.jpg",
"source": null,
"link": null,
"extension": "epub",
"duration": null,
"size": 4567444,
"width": null,
"height": null,
"description": null,
"score": null,
"createTime": 1753264933000,
"createUser": "1673603133161799680",
"updateTime": 1753264933000,
"updateUser": 1673603133161799680,
"tags": [
{
"name": "Social media design",
"id": 8223
},
{
"name": "Platform customization",
"id": 8247
},
{
"name": "cadahsjdkhasdhasjkdhajshdasjkhdajskhdjakshdasjhdajshdjkashd",
"id": 9084
},
{
"name": "asdashdlajksdhjkashdjksahdjashdlasdj",
"id": 9096
},
{
"name": "ccc",
"id": 9097
},
{
"name": "Web design",
"id": 8224
},
{
"name": "Interactive elements",
"id": 8270
}
],
"thumbnailAccessUrl": "https://example.com/assets/sample.jpg"
}
],
"traceId": "1753943463848693869"
}

Query custom metadata by asset ID

Endpoint: /metadata-records-by-ids

Method: POST

Description: Retrieve saved custom metadata values for asset IDs in bulk. IDs are omitted when custom metadata is disabled for the team or the asset has no metadata record.

Request parameters:

FieldTypeRequiredDescription
materialIdsList<Long>YesAsset IDs; maximum 50 per request

Response: Map<Long, Object>. Keys are asset IDs; values are metadata objects mapping field names to values, including recordId, materialId, and other fields.

Request example:

bash
curl --location --request POST 'https://open.musedam.ai/api/muse/metadata-records-by-ids' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{"materialIds":[6908914,6908820]}'

Example response:

json
{
"code": "0",
"message": "OK",
"result": {
"6908914": {
"materialId": 6908914,
"recordId": "rec_xxx",
"yourFieldName": "Custom value"
}
},
"traceId": "..."
}

Notes:

  • Only assets with metadata records are returned. IDs without records are omitted from result.
  • Uploading metadata uses fieldId (see the upload endpoint); this read endpoint uses field names as keys.

Query team metadata fields

Endpoint: /metadata-fields

Method: GET

Description: Query configured custom metadata field definitions for the current team. Use the returned field id as metadatas[].fieldId during upload. Returns an empty list if custom metadata is disabled.

Response: List<Object>; each item is a field definition:

FieldTypeDescription
idStringField ID; use as fieldId during upload
nameStringField name; use as name when modifying asset metadata
field_type / typeStringField type, such as text, number, or select; refer to the actual response

Request example:

bash
curl --location --request GET 'https://open.musedam.ai/api/muse/metadata-fields' \
--header 'Authorization: Bearer your_api_key'

Note: Built-in fields such as materialId also appear in the list. Filter them as needed.

Check transferred assets in bulk

Description: Determine whether assets were created by a member resource transfer, such as resources transferred to another member when someone leaves or is removed.

Endpoint: /check-transferred-materials

Method: POST

Request parameters: enterpriseTransferMaterialCheckReq

FieldTypeRequiredDescription
assetIdsList<Long>YesAsset IDs; equivalent to materialId and to id / assetIds elsewhere in the Open API

Response: Map<Long, Boolean>;

  • Key: An asset ID (assetId) from the request
  • Value: true for an asset created by a transfer; false otherwise, including nonexistent assets

Example request:

bash
curl --location --request POST 'https://open.musedam.ai/api/muse/check-transferred-materials' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"assetIds": [1234567890, 9876543210]
}'

Example response:

json
{
"code": "0",
"message": "OK",
"result": {
"1234567890": true,
"9876543210": false
},
"traceId": "17561978534182325498"
}

Notes:

  • The request parameter is named assetIds.
  • Nonexistent asset IDs are also returned, with a value of false.

Query asset users

Description: Query users who downloaded or shared an asset, with pagination. Operation logs are aggregated by user to return counts and most recent activity. The asset must exist in the current team.

Endpoint: /material-access-users-query

Method: POST

Request parameters:

FieldTypeRequiredDescription
assetIdLongYesAsset ID
operationTypesList<Integer>NoOperation types: 1 download, 2 share. Omit or leave empty to count both
pageIntegerNoPage number; defaults to 1
pageSizeIntegerNoPage size; defaults to 20, maximum 100

Response: Contains total and items. Each item has:

FieldTypeDescription
userIdLongUser ID
realNameStringFull name
nickNameStringNickname
emailStringEmail
phoneStringPhone number
avatarUrlStringAvatar URL
downloadCountLongDownload count; 0 if operationTypes excludes 1
lastDownloadTimeDateMost recent download time
shareCountLongShare count; 0 if operationTypes excludes 2
lastShareTimeDateMost recent share time
lastOperationTimeDateMost recent download or share time

Request example:

bash
curl --location --request POST 'https://open.musedam.ai/api/muse/material-access-users-query' \
--header 'Authorization: Bearer your_api_key' \
--header 'Content-Type: application/json' \
--data-raw '{
"assetId": 123456789,
"operationTypes": [1, 2],
"page": 1,
"pageSize": 20
}'

Notes:

  • Only operations by users in the current team are counted. Departed or deleted users are still returned if logs remain, including userId and counts; profile fields such as name may be empty.
  • One record is returned per userId, combining download and share statistics.
MuseDAM Developer PlatformAPI · Integrations · MCP
    Asset management | MuseDAM Developers