Estimate a Sume video clip in Python: list x 1.25, rounded up

A runnable Python script that prices a clip for Wan 3.0, MiniMax H3, H3 Max and Gemini Omni 1.1 Flash with integer micros, so the cents match the bill.

5 min readSume
All posts

You can price a Sume video clip before you submit it. For the per-second models the price is the catalog list rate times 1.25 times the seconds, rounded up to the cent. This Python script does the arithmetic in integer USD micros, because floating point can turn $0.3125 into a number that rounds the wrong way.

The script

The rate table copies the list rates from the video catalog, read 2026-10-05. Re-read GET /v1/video-router/models before you rely on it, because list prices come from the provider and can change. Seedance is priced per video token and is not included.

import math

LIST_MICROS_PER_SEC = {
    "wan-3.0": {"480p": 50_000, "720p": 100_000, "1080p": 200_000},
    "minimax-h3": {"480p": 50_000, "768p": 60_000},
    "minimax-h3-max": {"480p": 50_000, "768p": 80_000, "1080p": 160_000},
    "gemini-omni-flash-1.1": {"360p": 30_000, "720p": 100_000,
                              "1080p": 150_000, "4K": 300_000},
}


def sume_cents(model, resolution, seconds):
    micros = LIST_MICROS_PER_SEC[model][resolution] * 125 // 100 * seconds
    return math.ceil(micros / 10_000)


def main():
    jobs = [("wan-3.0", "720p", 5), ("minimax-h3-max", "768p", 8),
            ("gemini-omni-flash-1.1", "360p", 3)]
    total = 0
    for model, res, secs in jobs:
        c = sume_cents(model, res, secs)
        total += c
        print(f"{model} {res} {secs}s -> ${c / 100:.2f}")
    print(f"batch -> ${total / 100:.2f}")


if __name__ == "__main__":
    main()

What it prints

For those three jobs the script prints $0.63, $0.80 and $0.12, for a batch total of $1.55. Because each job rounds up on its own, sum the per-job cents, not the raw micros: the totals can differ by a cent per job.

What this is and is not

It is an estimate of the Sume billable amount. The admission docs say Sume reserves the estimated amount at submit and a successful completion captures it. Use the usage.cost in the poll response, or GET /v1/usage?job_id=..., as the record of what was charged.

Extending it

To add a model, copy its list_usd_micros_per_second_by_resolution from the catalog row into the table. To add a duration check, read supported_durations from GET /v1/videos/models, or capabilities.duration_seconds from GET /v1/video-router/models, and raise an error before you price an impossible clip. To read a live balance, call GET /v1/balance with your key and compare it with the batch total before you submit.

Keep the script's results next to the usage.cost you see after each job. If the two ever disagree for the same settings, read the catalog again. The most likely cause is a list-rate change, not a bug in the arithmetic.

Before you ship anything, read the live pages again: the catalog is public, the pricing page is public, and the docs describe the request fields. A blog post is a snapshot. The catalog, the plan grid and the error table are the things that change, so write your code to read them instead of copying numbers from a page, and re-check when a new model is added.

A good habit is a small log line per submit with the model, resolution, duration, estimated cost, job id and the Idempotency-Key you used. When a job misbehaves, those six fields answer most of the questions support will ask, and they let you compare your estimate with usage.cost and the usage ledger without re-running anything.

If you are new to the API, start with one clip, one model and the lowest resolution, read the full response once, and only then build a loop around it. Most surprises with video jobs come from fields that were defaulted, not from fields that were set.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume