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.

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.
| Step | State when step 3 returns 402 | What to do |
|---|---|---|
| 1. Generate | completed, usage captured | Keep the job id and the result artifact URL |
| 2. Trim | completed, usage captured | Keep the job id and the video_url from its result |
| 3. Captions | Rejected with 402 insufficient_credits | Add 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
- 429 on a chain step: retry with the same Idempotency-Key
A 429 on a trim or captions submit is rate_limited or queue_full. Wait for retry-after and resend the same body with the same Idempotency-Key.
- Brand name mispronounced by the AI voice? Four fixes and the cost
When a TTS voice says your brand name wrong, change the voice, the language, the spelling or the dictionary. Each retake on Sume costs 1 to 7 cents.
- Ack a Sume webhook in 10 s, then copy the 30-second MP4 later
Sume gives each delivery 10 seconds. Verify, store the job id, answer 204, and let a worker download the MP4 instead of doing it inside the handler.
- Ad run returns 400 invalid_attachment: count your 30 files first
A Format run carries at most 30 files, split 30 images, 10 videos, 10 audio. A Python counter for attachments plus media URLs inside input, before you call.
Written by Sume