Ten hook variants of a 9:16 ad from one curl loop on Seedance 2.5

Ten opening hooks, one shared body prompt, ten Video Router jobs. A shell loop with stable Idempotency-Keys and how to plan the cost of 12-second 9:16 clips.

5 min readSume
All posts

A shell loop is enough to make ten hook variants of one 9:16 ad: one POST /v1/video-router/generate per hook, each with its own Idempotency-Key. Seedance 2.5 accepts 4 to 30 seconds per the Sume docs, so a 12 second variant sits well inside its range and TikTok's 5 to 60 second App Bundle window.

Why vary the hook

Hooks are the first line of a script, and they are the cheapest thing to vary. The body of the ad stays the same, so you can compare hooks without changing anything else. The Video Router docs list seedance-2.5 at 480p, 720p and 1080p, and the job envelope is async.

One loop, ten keys

Name each variant by a short label and reuse the label in the key, so a retry returns the same job instead of making an eleventh. Idempotency-Key is how Sume dedupes.

hooks=("Stop scrolling" "Nobody tells you this" "I tried it for a week" \
  "Three seconds to read" "The mistake I made" "Before and after" \
  "Do this first" "A quiet upgrade" "Watch the counter" "One small change")
i=0
for h in "${hooks[@]}"; do
  i=$((i+1))
  curl -s -X POST https://api.sume.com/v1/video-router/generate \
    -H "Authorization: Bearer $SUME_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: hook-test-$i" \
    -d "{\"model\":\"seedance-2.5\",\"prompt\":\"Opening line on screen: $h. Then a product demo on a desk.\",\"resolution\":\"720p\",\"duration\":12,\"aspect_ratio\":\"9:16\",\"mode\":\"async\"}"
  echo
done

Track each job

The response is a job envelope. Keep each request_id with its hook label in a file, then poll GET /v1/jobs/:id/status and read GET /v1/jobs/:id/result when each is ready. Do not run more in parallel than your plan allows; check the generation admission rules in the docs before you scale the loop.

Plan the cost

Spend scales with output seconds and resolution, so plan the batch before you start. Sume bills the provider list rate times 1.25. Ten clips at 12 seconds is 120 output seconds of one model at one resolution, and you can multiply that by the live per-second rate from GET /v1/catalog rather than a number remembered from a blog post.

Change one thing at a time

Comparison needs control. Keep the resolution, duration, aspect ratio and the rest of the prompt fixed. Change only the opening line. If you also change the product shot, a difference in results has two possible causes.

What stays fixed and what changes across ten variants (TikTok App Bundle page read 2026-10-05)
FieldValueReason
modelseedance-2.5Same model
duration12Inside TikTok's 5 to 60 s App Bundle range
aspect_ratio9:16TikTok lists 9:16 at 720x1280 or larger
resolution720pCheck the real frame size with video inspect
Opening lineVariesThe one variable

Probe before upload

After the jobs finish, probe each file for width and height with video inspect before you upload. The Sume docs do not state the pixel size for each resolution tier, and TikTok's page lists 720x1280 as the minimum for 9:16 App Bundle, so measure rather than assume.

Write hooks as first seconds

Write the hooks as lines a person would say or show, not as prompts about style. A hook is judged by the first two seconds of the clip, so the prompt should say what appears first. If you want on-screen text, write it in the prompt as in the loop above, then check the stills to see whether the model rendered it as intended. Models are not reliable at text, so the safer route for exact words is to add them afterward as captions, with the captions API and authored cues.

Keep a ledger

Keep the list of variants in a file under version control, with the key, the hook and the job id. When the results are in, you can sort them against whatever metric you use to judge them. The loop above sends requests; it does not choose winners, and nothing in the Sume docs I read says a particular hook will perform better. Your own test, run on the platform, is the only evidence that counts.

Draft low, finalize high

If ten variants is more than you want to fund, run three first at 480p, look at the stills with video inspect, and promote only the promising hooks to 720p or 1080p. The seedance-2.5 envelope lists all three resolutions, so you change one field. Use new idempotency keys for the promoted runs, because reusing a key returns the first job instead of a new render.

Stop conditions

Decide in advance how many variants you will run and what you will do with the results. A loop makes it easy to spend on one more batch without a decision. Set a cap on the number of jobs, and stop the loop when you reach it, then review the stills before you spend again.

The takeaway

One loop, one changing variable, one key per job.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume