Failed AI video jobs: Google bills successes, Sume refunds the hold
Google says Veo videos are charged only when generated. Sume holds the price at submit, captures it on success and refunds it on failure or early cancel.

A failed AI video job is not charged on either path this page covers. Google's pricing page says that for Veo you are charged only if the video is successfully generated. On Sume the price is held when you submit, captured when the job completes, and refunded if the job fails or is canceled before capture. The difference is timing: Sume's hold ties up balance while the job runs.
The two billing lifecycles
Google's statement is from its pricing page, read 2026-10-09. Sume's states come from the usage and core workflow docs. Sume does not list Veo, so the left column describes Google's own billing rule for its models, not a Sume service.
| Step | Google (Veo, per its pricing page) | Sume (video jobs) |
|---|---|---|
| Submit | No charge stated | Balance hold: provider list x 1.25 |
| Job succeeds | Charged | Captured; usage.cost is the billable amount |
| Job fails | Not charged | Hold refunded |
| Cancel before capture | Not stated | Hold refunded |
| Queue is full | Not stated | 429 queue_full; the hold is given back |
What a hold looks like in money
A 12-second Wan 3.0 job at 1080p holds 12 x $0.25 = $3.00. While it runs, $3.00 of your balance is open as a hold and not spent. If it completes, $3.00 is captured. If it fails, the usage page's refunded status applies, and the open amount returns. The usage summary separates held_usd_micros, which is not spend yet, from refunded_usd_micros, which is also not spend.
A refunded row keeps its hold amount in billable_amount_usd_micros, per the usage page, so do not sum rows yourself; use the job id with the usage summary.
Cases where money stays reserved
A job in queued or processing is not a failure, and its hold stays open until the job reaches a terminal state. If you submit a batch and walk away, the open holds can block later submits with a 402 even though nothing has been spent. Look at the open amount before you diagnose the error.
If a job completes but you cannot use the output, that is a quality problem, not a failed job, and the capture stands. Retake with a corrected prompt, and use a lower tier for the experiments. The usage entries for each job id show which jobs were captured and which were refunded.
What to check after a failure
Read the job's public error: category, stage, retryability and next action. For quota the next step is to add funds or lower the cost, for queue it is a retry with the same idempotency key, and for generation_rejected it is to correct the unsupported input. Retry the submit with the same Idempotency-Key so that a replay returns the original job. A new key is a new paid job with a new hold.
Sources
Related posts
More in Developers
- Audio detach retry: what idempotency_hit true means for the $0.01
Retrying an audio detach with the same Idempotency-Key and body returns the first job (idempotency_hit true): $0.01 once. A changed body returns 409.
- Audio job failed: read /events and /status before you retry
A failed TTS, STT or music job is terminal. Read GET /v1/jobs/{id}/events and status, fix the cause, then resubmit under a new key. A new TTS job bills again.
- Avatar video image URLs: product_image, scene photo and backgrounds
Sume avatar video takes three kinds of image URL: product_image, scene.image_url and scene-background images. All must be public HTTPS. Checks to run first.
- File-size cap and max length: the average bitrate ceiling
Divide a platform's size cap by its longest allowed video to get an average bitrate ceiling: LinkedIn about 2.2 Mbps, TikTok 6.7, Pinterest 17.8. Python check.
Written by Sume