A brand 'Wrapped' year-in-review video: 100 customers for $20.10
Spotify Wrapped made the year-in-review a format. Render one clean 5-card video and burn each customer's numbers in with a caption job: 100 for about $20.10.

A brand 'Wrapped' video is one clean five-card MP4 with each customer's numbers burned in by a caption job. At $0.20 per caption job and $0.10 for the shared base, 100 personal videos cost $20.10 on Sume, and 1,000 cost $200.10, before the music bed ($0.125).
Why this format: Wikipedia's Spotify Wrapped article, read 2026-10-03, says it debuted in December 2016, shifted to a social story format in 2019, shows users' top five artists, songs and genres, launched its 2025 version on 3 December, and inspired Apple Music Replay, YouTube Music Recap and Tidal My Rewind. People share a recap that is about them.
The pattern
Design five cards that never change: an intro, a count, a favorite, a streak and a thank-you. Render them once with Timeline as five 4-second still slots ($0.10 for the 20 seconds). The text that changes is short: a name, a number of orders, a favorite product. Put those in cues and burn them with one caption job per customer. The base file is untouched, so you can rerun a single customer whose number was wrong.
| Customers | Base render | Caption jobs | Total (without music) |
|---|---|---|---|
| 10 | $0.10 | 10 x $0.20 = $2.00 | $2.10 |
| 100 | $0.10 | 100 x $0.20 = $20.00 | $20.10 |
| 1,000 | $0.10 | 1,000 x $0.20 = $200.00 | $200.10 |
Pace the queue
Hundreds of jobs submitted in one burst can hit the workspace's admission limits. Our 300 UGC clips post walks through the queue_full 429 and how to pace; reuse a unique Idempotency-Key per customer so a retry cannot double-bill. Use webhooks or poll GET /v1/jobs/{id}/status rather than holding a connection open.
import os, sys, uuid, requests
def main():
key = os.environ.get("SUME_API_KEY", "")
if not key:
sys.exit("Set SUME_API_KEY first")
body = {
"video_url": "https://media.sume.com/artifacts/YOUR_ARTIFACT/clean.mp4",
"style": "slam",
"cues": [
{"text": "Jamie, your 2026 with us", "start": 0.0, "end": 3.5},
{"text": "24 orders. Top pick: oat latte", "start": 4.0, "end": 8.0},
],
}
resp = requests.post(
"https://api.sume.com/v1/video-captions",
json=body,
timeout=60,
headers={"Authorization": "Bearer " + key,
"Idempotency-Key": str(uuid.uuid4())},
)
print(resp.status_code, resp.json())
if __name__ == "__main__":
main()
Privacy first
Use only data customers agreed you could use this way, and do not put sensitive details on a card someone may share on a public feed. Spotify's version is built from the user's own listening history; yours is built from yours, and the same care applies.
What Sume does and does not do
- Does: render the base video, burn per-customer text and return one MP4 per customer.
- Does not: pull your customer data, rank customers or send emails.
- Does not: guarantee every name renders cleanly. Test names with accents, apostrophes and long strings on a short clip first.
Sources
Related posts
More in Use cases
- Brazil CONAR 2026 guide: AI avatars as influencers, and AI labels
CONAR's influencer guide took effect 1 June 2026, adds a section on AI and counts avatars as influencers. What it asks of an AI video ad, and what it does not.
- Burn captions on a silent product video with authored cues
A silent clip fails Sume captioning with caption_no_speech. Pass cues or segments with text, start and end to burn your own copy, no transcription step.
- BNPL hits $21.3B in the holiday forecast: add an installment line
Adobe forecasts $21.3B in buy now pay later spend this season, 82% on mobile. How to add an installment text line to a product clip without re-rendering it.
- Cafe or bakery weekly clips: five photos, five 5-second clips
Animate five product photos into vertical clips with seedance-2.5 first_frame, then join them in Timeline 1.0. What the API accepts and what it can't promise.
Written by Sume