Attach custom key-value metadata to design blocks for tracking asset origins, storing application state, or linking blocks to external systems.
Metadata lets you store string key-value pairs on any design block. The data is invisible to end users, but it is saved with the scene and restored when the scene is loaded again.
This guide covers how to set, retrieve, list, remove, and persist metadata on blocks. The snippets use a block named trackedBlock; in your app, pass the block you want to tag.
Set Metadata#
Use engine.block.setMetadata() to attach a key-value pair to a block. Both the key and value are strings. If the key already exists, the new value replaces the old one.
engine.block.setMetadata(trackedBlock, key = "externalId", value = "asset-12345")engine.block.setMetadata(trackedBlock, key = "source", value = "user-upload")engine.block.setMetadata(trackedBlock, key = "uploadedBy", value = "designer@example.com")You can attach multiple metadata entries to the same block. Each entry is independent and can be read, updated, or removed by key.
Get Metadata#
Use engine.block.hasMetadata() before engine.block.getMetadata() when the key may be absent. getMetadata() fails if the key does not exist, so the guard keeps optional reads explicit.
val externalId = if (engine.block.hasMetadata(trackedBlock, key = "externalId")) { engine.block.getMetadata(trackedBlock, key = "externalId")} else { null}This pattern is useful when metadata comes from user-generated templates, imported scenes, or older scene versions.
List All Metadata Keys#
Use engine.block.findAllMetadata() to list every metadata key stored on a block. The sample turns those keys into a map so the app can inspect or sync the current metadata state.
val metadataEntries = engine.block .findAllMetadata(trackedBlock) .associateWith { key -> engine.block.getMetadata(trackedBlock, key = key) }For blocks without metadata, engine.block.findAllMetadata() returns an empty list.
Store Structured Data#
Metadata values are strings. To store structured data, serialize the object first and parse it again after reading the value.
val generationInfo = JSONObject() .put("source", "internal-generator") .put("model", "image-model-v1") .put("appVersion", "2026.1")
engine.block.setMetadata( trackedBlock, key = "generationInfo", value = generationInfo.toString(),)
val decodedInfo = JSONObject(engine.block.getMetadata(trackedBlock, key = "generationInfo"))val generationModel = decodedInfo.getString("model")This works for app-owned configuration, generation parameters, creator details, or any small payload that can be represented as a string.
Remove Metadata#
Use engine.block.removeMetadata() to delete a key-value pair. Guard with engine.block.hasMetadata() when the key may not be present.
if (engine.block.hasMetadata(trackedBlock, key = "uploadedBy")) { engine.block.removeMetadata(trackedBlock, key = "uploadedBy")}After removal, read the metadata state again when your app needs to update UI, sync state, or verify a cleanup step.
val hasUploadedByAfterRemoval = engine.block.hasMetadata(trackedBlock, key = "uploadedBy")val remainingKeys = engine.block.findAllMetadata(trackedBlock)Metadata Persistence#
Metadata is preserved when you save scene data with saveToString() or saveToArchive(). Reload scene strings with engine.scene.load(). For archive data, write the archive to a URI and reload it with engine.scene.loadArchive().
val savedScene = engine.scene.saveToString(scene = scene)engine.scene.load(scene = savedScene)
val reloadedBlock = engine.block.findByType(DesignBlockType.Graphic).first()val persistedExternalId = engine.block.getMetadata(reloadedBlock, key = "externalId")Troubleshooting#
getMetadata Fails#
If getMetadata() fails, the key is not set on the block. Check with hasMetadata() before retrieving optional metadata.
Metadata Is Missing After Reloading#
Confirm that your app saves editable scene data, then reloads it with the matching API. Use engine.scene.load() for strings from engine.scene.saveToString(). Use engine.scene.loadArchive() for archives from engine.scene.saveToArchive() after writing the archive data to a URI. Image, video, and PDF exports do not preserve editable block metadata.
Metadata Values Are Large#
Keep metadata values small. For large payloads, store a stable external ID or URL in metadata and keep the full data in your app backend or local storage.
API Reference#
| Method | Description |
|---|---|
engine.block.setMetadata(block=_, key=_, value=_) |
Set or replace a metadata value on a block |
engine.block.getMetadata(block=_, key=_) |
Read the metadata value for a key |
engine.block.hasMetadata(block=_, key=_) |
Check whether a block has a metadata key |
engine.block.findAllMetadata(block=_) |
List all metadata keys stored on a block |
engine.block.removeMetadata(block=_, key=_) |
Remove a metadata key from a block |
engine.scene.saveToString(scene=_) |
Serialize the editable scene data as a string |
engine.scene.saveToArchive(scene=_) |
Serialize the editable scene and referenced assets as an archive |
engine.scene.load(scene=_) |
Load a scene from a serialized scene string |
engine.scene.loadArchive(archiveUri=_) |
Load a scene from a saved archive URI |
engine.block.findByType(type=DesignBlockType.Graphic) |
Find blocks of a specific type after loading |