Inngest retries a failed step four times: key the Sume submit
Inngest's default is four retries after the first attempt, five in all, and side effects are not exactly-once. Give the Sume submit an Idempotency-Key.

A step that submits a paid Sume job can run up to five times, and the Inngest docs say side effects are not guaranteed exactly-once. Send an Idempotency-Key derived from the event data so repeated attempts return one job.
Inngest facts are from its error-handling and Functions docs; Sume facts from Communication modes and Errors and credits, read 2026-10-01.
How many attempts does a step get?
The error-handling docs give the default as four retries after the first attempt, so five attempts in total. They tell you to use idempotency keys for writes, payments and messages, because side effects are not guaranteed exactly-once.
| Attempt | Reaches Sume | With a stable key |
|---|---|---|
| 1 | Job created, response lost | Job exists |
| 2 to 5 | Same request again | Original job returned, one charge |
| Any, with a different key | Request again | A new paid job each time |
Where does the key come from?
From the event, not the step. Use a field that is the same on every attempt, such as an order id plus a revision. Sume treats an exact retry under one key as the same job, and a changed payload under the same key returns 409 idempotency_conflict.
What does the function look like?
The function config shape below follows the current Inngest docs example. Return the job id from the step and do the waiting somewhere else, by webhook or a poll that honors next_poll_after_seconds.
import { createSumeClient, generateVideoV1 } from "@sume-com/sdk";
import { inngest } from "./client";
const client = createSumeClient({ apiKey: process.env.SUME_API_KEY! });
export const makeVideo = inngest.createFunction(
{ id: "make-video", triggers: { event: "shop/video.requested" } },
async ({ event, step }) => {
return await step.run("submit-sume-job", async () => {
const { data, error } = await generateVideoV1({
client,
headers: { "idempotency-key": "video-" + event.data.orderId },
body: { prompt: event.data.prompt, mode: "async" },
});
if (error) throw new Error(JSON.stringify(error));
return data!.data.request_id;
});
},
);Should every error retry?
No. A 400, 401 or 402 fails identically each time; stop those early with the pattern in the NonRetriableError post.
Sources
Related posts
More in Developers
- Instagram API 100 posts per 24 hours: size your bulk queue
Instagram limits API-published posts to 100 in a moving 24-hour period, checked at content_publishing_limit. A Sume bulk queue also tops out at 100 items.
- Instagram API error: Maximum number of sponsors exceeded (2)
Instagram's publishing error table lists 'Maximum number of sponsors exceeded. Limit is 2 per post.' and 'Cannot tag yourself as sponsor.' How to prevent both.
- Edits 15-minute export vs Sume's 900-second trim and detach cap
Edits now exports up to 15 minutes on iOS. Sume trim and audio detach also top out at 900 seconds of output, from a source up to 1800 seconds.
- Edits compare 3 reels: read the clips with Sume video inspect
Instagram Edits compares up to 3 reels by views and watch time. Sume video inspect adds what the clips contain: probe facts, stills and an optional transcript.
Written by Sume