CI HUBCI HUB SDK
Advanced

Asset Types

The type field on an asset controls how CI HUB displays it and what actions are available. Three modes exist: default (file), PRODUCT, and SNIPPET.

Default (file asset)

When type is omitted or undefined, CI HUB treats the asset as a regular file — it has a thumbnail, a downloadable file, and can be placed into creative documents.

This is the most common type. Most DAM adapters return file assets exclusively.

PRODUCT

Entity/composite content that has no single downloadable file. The asset card shows metadata and nested child assets instead of a download button.

Use PRODUCT when:

  • The item is a content object containing references to other files
  • The platform models structured content (product data, content items) alongside media files

When type: 'PRODUCT', set thumbnailUrl and downloadUrl to undefined. The asset's values array becomes the primary display — these are the metadata entries shown on the asset card. Child files appear as values entries with type: 'ASSET'.

Example - some adapters uses PRODUCT for ContentItem and Virtual content types:

if (item.content && ['ContentItem', 'Virtual'].includes(item.contentType)) {
  const content = item.content

  asset.thumbnailUrl = undefined
  asset.downloadUrl = undefined
  asset.type = 'PRODUCT'
  asset.values = await getValues(req, content, selectedSystem)
}

The getValues function resolves linked content into an array of metadata entries. Linked files become values entries with type: 'ASSET' containing a mini-asset object (id, name, thumbnailUrl, downloadUrl, conversions, capabilities):

const getValues = async (req, item, selectedSystem) => {
  let values = []
  const contentIds = []

  for (const [key, value] of Object.entries(item || {})) {
    if (value instanceof Array) {
      value.forEach(entry => {
        if (entry instanceof Object && entry._targetId) {
          contentIds.push(entry._targetId)
        }
      })
    } else if (value instanceof Object && value._targetId) {
      contentIds.push(value._targetId)
    } else if (value['x-default']) {
      values.push({
        id: key,
        name: key,
        type: 'TEXT',
        value: getXDefault(item[key])
      })
    }
  }
  if (contentIds.length > 0) {
    const contentValues = await getContentValues(req, selectedSystem, contentIds)
    values = values.concat(contentValues)
  }

  return values
}

SNIPPET

Non-file metadata-only content. The asset has no downloadable file and no thumbnail. CI HUB shows the asset name and metadata but disables download and placement actions.

Use SNIPPET when the item is purely textual or structural — notes, text blocks, non-renderable entries.

Example - some adapters marks OneNote items as SNIPPET:

const asset = {
  id: item.id,
  name: item.name,
  fileSize: item.size,
  mimeType: (item.file && item.file.mimeType) || mime.lookup(item.name) || 'application/octet-stream',
  version: 1,
  type: (isOneNote && 'SNIPPET') || undefined,
  values: [],
  capabilities: { ...defaultAssetCapabilities, canUpdateAsset: !isOneNote, canRenameAsset: !isOneNote }
}

Summary

typeHas fileThumbnailDownloadPlacementPrimary display
(empty)YesYesYesYesFile preview
PRODUCTNoNoNoNovalues array (metadata + nested assets)
SNIPPETNoNoNoNoAsset name + metadata

See Metadata Values for how to populate the values array on PRODUCT assets.

On this page