402 on the caption step after a paid generate and trim: what now

A 402 insufficient_credits at the caption step means admission failed before provider work. The render and trim jobs you paid for stay completed.

4 min readSume
All posts

When a generate, trim and captions chain fails with 402 insufficient_credits on the caption step, the generate and trim jobs are already completed and captured, and the 402 means Sume could not reserve the caption job's estimate. No provider work started for that submit. Keep the trim result URL, fix the balance, and resubmit only the caption step with the same Idempotency-Key and the same body.

What each step looks like when the 402 lands

A 402 is an admission failure on one submit. It is not a verdict on the earlier jobs. The docs list it as an immediate rejection: the workspace balance cannot cover the estimated generation cost, and it happens before provider work starts.

State of a chain at a 402 on step 3 (read 2026-10-05)
StepState when step 3 returns 402What to do
1. Generatecompleted, usage capturedKeep the job id and the result artifact URL
2. Trimcompleted, usage capturedKeep the job id and the video_url from its result
3. CaptionsRejected with 402 insufficient_creditsAdd funds or choose a cheaper request, then resubmit with the same key

Fixing the cause

The docs' client guidance for 402 is to upgrade the plan, wait for included Gen$, or submit a less expensive request, and it explicitly says not to invent prepaid top-ups. The TypeScript SDK maps the case to a typed error: SumeInsufficientCreditsError for 402, and the docs' run-helper example reads next_action: "add_funds" from it.

Do not retry in a tight loop. A 402 does not clear on its own, so a backoff loop only burns request budget. Retry after something changed: a plan change, a balance change, or a smaller request.

Why the same key is right

Because the failed admission released any reservation and created no job, resubmitting is safe. Send the same Idempotency-Key with the same body so that, if your first attempt did create a job and the response was lost, the retry returns that job and does not bill a second one. If you change the body, for example a different style, use a new key: a reused key with a different payload returns 409 idempotency_conflict.

If your chain runner had already moved on, do not restart from step 1. Store the job id and result URL for each finished step, and resume from the first step without a stored result.

A guard before the chain starts

Check the balance and the cost of the whole chain before step 1: GET /v1/balance is the docs' suggested read for conservative decisions. A chain that needs $0.22 of trim and caption spend after its render should confirm that headroom first, because the failure that costs the most is the one that strands finished work.

How to resume after a top-up

Because the 402 is an admission failure, nothing is half-done on the caption side. Add credits, then resend the caption request with the same Idempotency-Key and the same body. If the earlier call was never admitted, the key has no job attached and the resend creates one. If it was admitted after all, the resend returns that job.

Do not re-run the generate and trim steps. Both are completed jobs with stored ids, and their results are still readable. The only step that has to run again is the one that returned the 402.

Before you retry in a loop, check the balance. A 402 does not carry a retry-after, because waiting does not fix it. A retry loop on a 402 only adds noise to your logs and uses up your request budget.

  • Stop the chain at the 402; do not poll a job that was never created.
  • Keep the completed render and trim ids.
  • Top up, then resend the same key and body.
  • Alert a person: a 402 needs money, not time.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume