Assets

Asset families and assets — how catalog media is classified, the storage/external binding the database enforces, and why delivery_path is never the identifier.

An asset is the catalog's record of a piece of media. The bytes live in Storage; the asset row says what the file is, which class of media it belongs to, and which product attribute may reference it.

EntityBase path
asset_families/v1/products/asset_families
assets/v1/products/assets

Asset families

A family is a class of media with one shared shape — packshots, datasheets, installation videos.

Asset family
{
  "code": "packshots",
  "labels": { "en": "Packshots", "de": "Packshots" },
  "naming_convention": {
    "source": "sku",
    "pattern": "{sku}_{index}",
    "allowed_extensions": ["jpg", "png", "webp"]
  }
}

naming_convention is how a file of this family is named, so a bulk import can bind a file to a product without a mapping table: source is the product value the name is built from, pattern how it is assembled, allowed_extensions what may be uploaded.

Like a reference entity, an asset family carries its own attributes — declare them with entity_type: "asset" and entity_ref: "<family code>".

Assets

Asset — platform storage
{
  "asset_family_id": "",
  "code": "ACME-4711-BLK_1",
  "source": "storage",
  "storage_asset_id": "ast_01hxyz…",
  "attribute_values": { "common": { "alt_text": "Cordless drill, front" } }
}
Asset — external host
{
  "asset_family_id": "",
  "code": "ACME-4711-BLK_video",
  "source": "external",
  "external_url": "https://cdn.example.com/acme/4711/assembly.mp4"
}
FieldMeaning
codeStable identifier within its family — the value a product's media attribute stores.
asset_family_idWhich family. A create with none falls back to the tenant's default_asset_family setting.
sourceWhere the bytes live: storage (this platform's object store) or external (somebody else's host).
storage_asset_idThe stable ast_… id of the storage object. Required when source is storage.
external_urlAbsolute URL. Required when source is external.
delivery_pathThe path the CDN serves the asset under.
attribute_valuesThe asset's own modelled values, same four buckets as a product.

The database enforces the pair, so neither half of a source/identifier combination can be stored on its own.

Two rules worth internalising

Never join on delivery_path. It is the convenient value for rendering and it changes when the file is moved. storage_asset_id survives a rename or a folder move, which is exactly why it and not the path is the identifier.

External URLs are gated, and only here. source: "external" is accepted only when the tenant has allow_external_media on and the host is on its external_media_allowed_hosts list. POST /v1/products/assets is the only place an external URL can enter the catalog, so it is the only place those checks exist.

Getting the bytes there

Uploading a file is a Storage operation, not a catalog one. Upload first, take the returned ast_… id, then create the asset row that points at it. See Storage for the upload paths and Import and export for the bulk version.

Where a product references it

A media or media-collection attribute stores the asset code:

attribute_values
{ "common": { "images": ["ACME-4711-BLK_1", "ACME-4711-BLK_2"] } }

Which attribute carries the main image is a family setting — families.image_attribute, read by grid thumbnails and pickers. See Data model.

Where to go next

Was this page helpful?