Sume SDK idempotency key: idempotencyKey option or header?

subscribeFormatRun takes an idempotencyKey option and generates one for you; generated operations like generateVideoV1 need the idempotency-key header.

5 min readSume
All posts

With @sume-com/sdk, subscribeFormatRun takes an idempotencyKey option and generates a UUID when you omit it. Generated operations such as generateVideoV1 take the key as a request header instead: headers: { "idempotency-key": ... }.

Mixing them up is easy, and the cost is real: the client retries a POST only when it carries an Idempotency-Key, so a missing key means no automatic retry rather than a duplicate bill.

Where does each helper want the key?

Both snippets come from the SDK docs. subscribeFormatRun documents idempotencyKey (auto UUID, null to send none) and notes a replay of a finished run returns immediately. The generation-job example passes headers: { "idempotency-key": crypto.randomUUID() } to generateVideoV1.

Idempotency key by call (SDK docs read 2026-10-02)
CallHow to pass the keyIf omitted
subscribeFormatRunidempotencyKey optionAuto UUID
generateVideoV1 and other generated operationsheaders: { "idempotency-key": ... }No key, no automatic POST retry
Raw HTTPIdempotency-Key headerNo safe replay

Should the key be random or derived?

For a one-shot call a random UUID is fine. For work you might replay from your own queue, derive the key from your own record, such as an order id and version, so a restart reuses it. The SDK docs' example uses order-8823-promo-v1.

Reuse a key only for the same operation and payload. The API answers 409 idempotency_conflict when a key is reused for a different one.

Why does a retry need the key?

The client retries 408, 429, 5xx, and transport failures twice by default with exponential backoff and jitter, honoring retry-after. A POST is retried only with an Idempotency-Key, because a replay would otherwise start and bill a second run.

The same rule is behind the docs' advice not to resubmit a paid request just because your local worker timed out.

Generated operations do not throw

They resolve with { data, error, response }, so check error before reading data.

import { createSumeClient, generateVideoV1 } from "@sume-com/sdk";

const client = createSumeClient({ apiKey: process.env.SUME_API_KEY! });

const { data, error } = await generateVideoV1({
  client,
  headers: { "idempotency-key": "clip-2026-10-02-001" },
  body: { prompt: "Slow push-in on a ceramic mug", mode: "async" },
});
if (error) throw new Error(JSON.stringify(error));
console.log(data!.data.request_id);

What Sume does not do

The SDK is server-side only: the API key spends your credits and there is no browser-safe variant. Put your own endpoint in front and attach the key there.

Quick checklist

The points above reduce to a short list you can paste into a runbook.

  • Pass idempotencyKey to subscribeFormatRun, or accept its generated UUID.
  • Pass headers idempotency-key to generated operations.
  • Derive the key from your own record when you may replay from a queue.
  • Reuse a key only for the same operation and payload.
  • Check error before data on generated operations, because they do not throw.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume