Shopify productReorderMedia: put the AI product video second

productReorderMedia is asynchronous and zero-based; list only the media you move. Put a Sume product clip after the hero image and poll the job.

5 min readSume
All posts

Use Shopify's productReorderMedia to decide where an AI-generated product clip sits in the gallery. It takes the product id and a moves list of media ids with a zero-based newPosition, runs asynchronously, and returns a job you poll. List only the media that need to change place; Shopify keeps the rest in their current relative order.

Facts about Shopify come from the productReorderMedia reference, read 2026-10-02, and the productVariantAppendMedia reference. Sume job facts come from Jobs and results.

Why does gallery order need its own call?

Upload order is arrival order. When a catalog job runs many Sume generations in parallel, the video for one product can finish before or after its images, and whatever you upload last appears last. A shopper opening the page then sees a detail shot first and never reaches the clip. Reordering after everything is attached fixes that without making you serialize generation.

Whether a video should sit first, second or last is a merchandising choice, not a Shopify rule, and Shopify's page makes no recommendation. Test it on your own traffic.

What does productReorderMedia return?

The inputs are id (the product) and moves, each a media id and a newPosition. The payload contains a job, a list of mediaUserErrors and a deprecated userErrors list. Because large media collections are slow to reorder, Shopify made the operation asynchronous: poll the returned job to learn when the change has reached all sales channels. It requires write_products.

Shopify's page does not give a maximum number of moves per request. If you reorder very large galleries, split the list and watch mediaUserErrors rather than assuming a ceiling.

productReorderMedia facts from Shopify's reference, read 2026-10-02
ItemDetail
Position indexZero-based newPosition
What to listOnly media that need repositioning
ExecutionAsynchronous; poll the returned job
Max moves per callNot stated on the page

How do I compute the moves list?

The helper below returns the minimum list for pinning chosen media at the front. It is plain Python with no network calls, so you can test it before you point it at a live product. Notice that it emits newPosition as a string because the sample in the comment is meant to be pasted into GraphQL variables; check your client library for how it types that field.

# Build the "moves" list for productReorderMedia (positions are zero-based).
# Only media that must change place go in; the rest keep their relative order.

def moves_for(current_ids, wanted_first):
    """current_ids: media ids in today's order. wanted_first: ids to pin at the front."""
    moves = []
    for new_pos, media_id in enumerate(wanted_first):
        if current_ids[new_pos:new_pos + 1] != [media_id]:
            moves.append({"id": media_id, "newPosition": str(new_pos)})
    return moves

current = ["gid://shopify/MediaImage/1", "gid://shopify/MediaImage/2",
           "gid://shopify/Video/9"]
print(moves_for(current, ["gid://shopify/MediaImage/1", "gid://shopify/Video/9"]))
# -> [{'id': 'gid://shopify/Video/9', 'newPosition': '1'}]
# Send as: productReorderMedia(id: $productId, moves: $moves) { job { id } mediaUserErrors { field message } }

How do I verify the order afterwards?

Query the product's media after the job reports completion and compare the order with what you intended. Because the reorder touches all sales channels, a storefront can lag the Admin API for a short time, and the page does not promise how long. Check the live page after the job is done, not during.

A simple audit script walks your product list, reads each gallery and flags products where the video is not at the position you chose. Run it after every bulk generation. For products where a Sume job failed, the audit should report a missing video rather than an error, so you can queue only those SKUs again with a fresh Idempotency-Key and leave the finished ones alone.

What about the Sume side?

A Sume video job reaches completed only after queueing and processing, and the docs say a queued job is a normal accepted state, not a stall. Wait for terminal status on every job for a product before you reorder, and keep the job ids next to the media ids so you can tell which asset is the clip. If a job fails, the product simply keeps its images; do not block the listing on the video.

For setting the order of variant-specific images, see the variant media post.

Sources

Related posts

More in Integrations

All Integrations posts

Written by Sume