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.

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.
| Item | Detail |
|---|---|
| Position index | Zero-based newPosition |
| What to list | Only media that need repositioning |
| Execution | Asynchronous; poll the returned job |
| Max moves per call | Not 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
- Shopify stagedUploadsCreate: fileSize is required for video
Uploading an AI product clip to Shopify takes a staged upload, and fileSize is required for VIDEO. Download the Sume MP4, count the bytes, then stage it.
- Slack Events API retries 3 times: keep one Sume run per event
Slack retries a missed Events API ack three times and can disable your subscriptions. Ack in 3 seconds and let an Idempotency-Key keep one Sume run per event.
- smolagents MCPClient: give a CodeAgent Sume's remote tools
Connect a smolagents CodeAgent to Sume's hosted MCP with MCPClient and the streamable-http transport, send an API key header, and wait on jobs correctly.
- Snap Marketing API ai_content_source: the AI declaration on Media
Snap added an ai_content_source attribute to the Media entity in its Marketing API on August 28, 2026. What the changelog says, and how to record it.
Written by Sume