Contents

Migrating to the App Asset Library

Move your screenshots, app previews, and in-app event media from the deprecated set-based resources to the asset library.

Overview

The asset library replaces an approach where each App Store surface owned its own media. When you use the asset library, you upload each image or video once into a per-app library, then create placements that position it on surfaces.

In the previous approach, you created an app screenshot set for a specific display target, uploaded screenshots into it, and repeated the whole process for every localization, every custom product page, and every in-app event. The same image uploaded ten times became ten separate records. This article maps the concepts from the new approach onto the previous one and walks through converting an existing integration.

For more information about the App Asset Library, see Understanding the App Asset Library.

Compare the two models

The asset library replaces the set-based resources, which are deprecated:

Asset library

Deprecated resource

Placement type and placement group on a placement

App Screenshot Sets

App Asset Library Images plus a placement

App Screenshots

Placement type and placement group on a placement

App Preview Sets

App Asset Library Videos plus a placement

App Previews

App Asset Library Images plus a placement

App Event Screenshots

App Asset Library Videos plus a placement

App Event Video Clips

Placement type and placement group on a placement

App Custom Product Page Screenshot Sets

App Asset Library Images plus a placement

App Custom Product Page Screenshots

Placement type and placement group on a placement

App Custom Product Page App Preview Sets

App Asset Library Videos plus a placement

App Custom Product Page App Previews

There are several conceptual shifts with the new asset library approach:

  • Sets disappear. A set existed to group media by display target within one localization. A placement carries its placementType and placementGroup directly, so there’s no container to create first. One fewer resource, one fewer round trip.

  • Assets are separate from their position. Previously, a screenshot record was its position on a product page. Now, an asset lives in the library and a placement points at it, which makes reuse possible.

  • Display targets become placement groups. Placement group identifiers that you read from the reference data replace the old display-type enumeration values.

  • Checksums go away. Committing an upload takes uploaded alone. There’s no sourceFileChecksum to compute.

  • Ordering is explicit. Instead of patching an ordered list of relationships on a set, post an ordering request naming the placements in sequence.

Rewrite the upload sequence

The new sequence removes the set and the checksum that the previous approach used. Previously, a screenshot upload took four resource-touching steps: find or create the screenshot set, reserve the screenshot against that set, upload the parts, then commit with a filename, size, and checksum.

Now, the steps are:

  1. Read the app’s asset library once with GET /v1/apps/{id}/assetLibrary (Read related asset library). Cache the id; every asset you create relates to it. The library ID is stable for the life of the app.

  2. Reserve the asset with POST /v1/appAssetLibraryImages (Create an app asset library image) or POST /v1/appAssetLibraryVideos (Create an app asset library video), relating it to the library rather than to a set.

  3. Upload the parts exactly as before, using the returned uploadOperations.

  4. Commit with uploaded: true, and nothing else.

  5. Create a placement with POST /v1/appAssetLibraryPlacements (Create an app asset library placement) naming the placementType, the placementGroup, the asset, and the target localization.

Steps 1 through 4 run once per distinct file. Step 5 repeats for each place the file appears, which is where the savings come from.

Replace display targets with placement groups

One of the biggest changes with the asset library approach is that display-target constants become runtime lookups. Your code now reads placementProfileGroups and placementTypes from the reference data and maps a target device family to a placement group identifier such as IPHONE_DYNAMIC_ISLAND_LARGE_PROFILE; previously, it held a table of display types.

Do this lookup rather than hard-coding the strings. Apple adds new device families to the reference data without an API version change, so an integration that reads the catalog picks them up and one that hard-codes it doesn’t.

Specifications behave the same way. You no longer decide which specification a file satisfies; App Store Connect matches the file during processing and reports the result as specId. Read that value back and confirm it’s the specification you intended. For more information about specifications, see Discovering asset specifications.

Understand asset library deduplication

The asset library makes manual deduplication unnecessary: upload each file once, then create a placement per surface. You no longer need to hash each file or remember which localizations already have it, and you can skip redundant uploads.

The practical consequence of the new approach is that your local bookkeeping changes shape. Instead of tracking “which screenshot record belongs to which set,” track “which library asset backs which placements.” Query it directly rather than storing it: GET /v1/appAssetLibraryImages/{id}/placements (List related placements) returns every placement that uses an asset.

Watch the deletion order

Asset library deletes don’t cascade like set-based deletes do, where removing a screenshot set removed its screenshots. You can’t delete an asset that has placements; the request fails with the code STATE_ERROR.ASSET_HAS_PLACEMENTS.

Plan the transition

A migration that runs in one pass per app works well:

  1. Read the reference data and build your device-family-to-placement-group map.

  2. Read the app’s asset library ID.

  3. For each distinct source file, upload it once and record the returned asset ID against your own identifier for that file.

  4. Create a placement referring to the corresponding asset for each localization and display target you previously populated.

  5. Post an ordering request per placement group to restore the display order.

  6. Verify by reading each localization’s placements relationship with sort=placementGroupPosition.

You can only create placements while the parent surface is editable, so migrate against an App Store version in PREPARE_FOR_SUBMISSION rather than one that’s already approved.

See Also

Essentials