Recipe: external (placeholder-first) upload

Recipe: external (placeholder-first) upload

Recipe: external (placeholder-first) upload

💡

Prompt example

Reserve an asset id first, then push the file into that placeholder, and optionally tag it.

Some flows need the asset id before the bytes land (to wire up references, pre-tag, or upload out-of-band). The pattern is: create a placeholder, then upload into that placeholder by passing its id as existing_asset_id (the distinguishing step vs a plain upload, which lets the platform mint a fresh id).

Pattern

  1. create_placeholder(parent_id, name) → reserved asset id (name must have an extension).
  2. Upload into the placeholder: upload_asset(name, existing_asset_id=placeholder_id,...).
  3. (Optional) bulk_update_metadata([placeholder_id], tag_ids=...) to tag it — Class B, non-prod (see components/*/bulk_update_metadata.md).
  4. (Optional) get(placeholder_id) to confirm placement once it settles.

Confinement: parent_id must be your run-root anchor (or a folder beneath it). The placeholder and its content stay under the folder you control.

Python

# components: create_placeholder, upload, get  (+ bulk_update_metadata, Class B)
def external_upload(sdk, parent_id, name, file, language_id=None, tag_ids=None):
    """Reserve an id, push `file` into it, optionally tag. Returns the placeholder id."""
    placeholder_id = create_placeholder(sdk, parent_id, name)  # name needs an extension
    # Upload INTO the placeholder: existing_asset_id = placeholder_id.
    sdk.upload_asset(name, placeholder_id, None, "replace", file, parent_id, language_id)
    if tag_ids:  # optional, Class B
        sdk.bulk_update_metadata([placeholder_id], None, None, tag_ids, None)
    return placeholder_id

JavaScript

// components: createPlaceholder, upload, get  (+ bulkUpdateMetadata, Class B)
export async function externalUpload(sdk, parentId, name, file, languageId = null, tagIds = null) {
    const placeholderId = await createPlaceholder(sdk, parentId, name); // name needs an extension
    // Upload INTO the placeholder: existingAssetId = placeholderId.
    await sdk.uploadAsset(name, placeholderId, null, "replace", file, parentId, languageId);
    if (tagIds) { // optional, Class B
        await sdk.bulkUpdateMetadata([placeholderId], null, null, tagIds, null);
    }
    return placeholderId;
}

Notes

  • The placeholder id is stable across the upload — that is the whole point of this flow.
  • upload_asset positional args are (name, existing_asset_id, related_content_id, upload_overwrite_option, file, parent_id, language_id); "replace" overwrites the placeholder's (empty) content.
  • The tagging step uses bulk_update_metadata, which is Class B (non-prod); skip it for a Class A run.