Use your ad variant id as the Idempotency-Key on Sume

Name each ad variant once and send that name as the Idempotency-Key. Retries do not double-bill, and the receipt echoes it back so results map to your ad names.

5 min readSume
All posts

Make the Idempotency-Key a stable name for the variant, such as spring-mug-hookB-endingC-v1, and send it on every submit. Sume's /v1/videos route supports the Idempotency-Key header, and a Format run receipt carries it back in trigger.idempotency_key. A retry after a timeout then returns the existing job instead of creating and billing a second one, and your ad platform naming and your Sume jobs share one string.

What the key does on each route

The behavior differs slightly by route, so check which one you are on. The facts below come from the Sume docs for /v1/videos and for Format runs and bulk queues.

Idempotency behavior in the Sume docs, read 2026-10-07
RouteSame key, same bodySame key, different body
POST /v1/videosSupported via the Idempotency-Key header409 conflict
POST /v1/formats/{handle}/{slug}/runs200 with the original run and idempotency_hit true409 idempotency_conflict, nothing runs
POST /v1/formats/{handle}/{slug}/bulk-runs202 with the queue that already exists409 idempotency_conflict, details.queue_id names the original

Choose a naming scheme before you generate

A good key encodes the things you will want to filter on later and a version you bump on purpose. Campaign, hook letter, ending letter and version fit in a short string. Do not put customer data or secrets in a key, because it appears in receipts.

The version suffix is the control you use deliberately. If a clip was bad and you want a new take with the same prompt, bump v1 to v2. If you reuse v1 with the same body you get the old job back, which is the point of idempotency, and you pay nothing extra.

  • campaign-hook-ending-v1 for single clips.
  • One key per bulk batch, with a fresh value for each new batch, since a replayed bulk key returns the old queue.
  • Never reuse a key with an edited prompt; you will get a 409.

Reading the key back

On Format runs, the receipt's trigger object includes source api and the idempotency_key you sent. That lets a webhook handler or a nightly reconciliation job look up the variant by the name you chose, with no side table of job ids. For /v1/videos, store the returned id against your key at submit time, since the 202 body carries id, polling_url, status and model.

Bulk queues have an extra caution. The scope of a bulk key is one Format, and a replay returns 202, not 200, and has no idempotency_hit field. If you resend a batch after an ambiguous failure, compare the returned queue's items with your sheet before assuming it is new.

Example: submit with a variant key

The Node snippet below submits one variant and prints the job id next to the key. Run it twice with the same body and you should see the same id both times.

const key = 'spring-mug-hookB-endingC-v1';
const body = { model: 'seedance-2', prompt: 'Hook B, ending C: mug on a desk', duration: 6, aspect_ratio: '9:16' };
fetch('https://api.sume.com/v1/videos', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SUME_API_KEY}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': key,
  },
  body: JSON.stringify(body),
})
  .then((r) => r.json())
  .then((j) => console.log(key, j.id, j.status));

Concurrent duplicates and the in-use error

Format run creates add one more case. If the same key arrives twice at the same moment, one request wins and the other gets 409 idempotency_key_in_use, which the docs mark as retryable. Wait about a second and send again, and you receive the original run. This is the situation you hit when a queue worker and a retry timer both fire for the same variant, so a client that treats every 409 as fatal will wrongly abandon a variant that was in fact submitted.

A small rule covers it: on 409 idempotency_key_in_use, sleep and resend the identical body; on 409 idempotency_conflict, stop and look at your code, because you changed something that should have been fixed for that key.

Reconciling against the ad platform

The reason to bother is the join. Ad platforms let you name ads and ad sets, and when a report arrives you want to ask which Sume job made the winner and what it cost. If your ad name and your Sume key are the same string, that is a lookup. If they are not, someone maintains a spreadsheet that drifts.

Keep one table with the key, the Sume job or run id, the model id, the usage amount, and the ad platform ad name. Fill the first four at generation time and the last at upload. Nothing in this table needs a Sume feature beyond the key and the receipt.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume