sync-3 lip sync takes 10-15 min: async job and webhook pattern

Sync lists sync-3 at about 10-15 minutes for a 30 s video. Do not hold a request open: submit async, take a terminal webhook, and keep polling as a backup.

4 min readSume
All posts

Sync's generation-times page puts sync-3 at about 10-15 minutes for a 30-second video and about 45-55 minutes for two minutes. Any job that long should be submitted asynchronously: on Sume the default mode is async, sync and subscribe waits stop at 30 seconds, and a webhook fires on terminal states only.

Timings are Sync's estimates; Sume behavior is from Jobs and results and Generation admission, read 2026-10-01.

How long does lip sync take by model?

Typical times from Sync's generation-times page, read 2026-10-01. Sync calls them estimates.
Model30 s video2 min video
lipsync-2about 1-3 minabout 4-8 min
lipsync-2-proabout 2-5 minabout 6-12 min
sync-3about 10-15 minabout 45-55 min
react-1about 1-2 minn/a (max 15 s input)

How does Sync say to track a generation?

Poll the generation endpoint, recommended every 10 seconds, until the status is COMPLETED, FAILED or REJECTED, or configure a webhook, which the page calls more efficient for production. It also warns against resubmitting a stuck job because that adds queue entries without canceling the original.

What is the matching pattern on Sume?

Sume's default async mode returns 202 with the job envelope and polling URLs. sync and subscribe wait at most 30 seconds; if the job is not terminal, poll and do not resubmit. The webhook schema says delivery is terminal-only (job.completed, job.failed, job.canceled) with no progress callbacks, so keep status_url polling as a backup. The docs say to prefer async submit with an idempotency key in production. See also sync vs async video generation.

const API = "https://api.sume.com";
const headers = {
  Authorization: "Bearer " + process.env.SUME_API_KEY,
  "Content-Type": "application/json",
  "Idempotency-Key": "avatar-batch-001-item-001",
};

const res = await fetch(API + "/v1/avatar-1.0/generate", {
  method: "POST",
  headers,
  body: JSON.stringify({
    avatar_handle: "studio_presenter",
    input: { type: "prompt", prompt: "Friendly studio presenter" },
    mode: "async",
  }),
});
const job = await res.json();
const statusUrl = new URL(job.status_url, API);

let state = { terminal: false };
while (!state.terminal) {
  await new Promise((r) => setTimeout(r, 10000));
  state = await (await fetch(statusUrl, { headers })).json();
}
console.log(state);

What should I avoid?

Do not treat a client timeout as a failure and resubmit the paid request; read the same job id instead. Poll with backoff across many jobs rather than in a tight loop.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume