Perl HTTP::Tiny: submit a MiniMax H3 video job and save it
A 23-line Perl script with core modules only: POST /v1/videos for minimax-h3, poll, download. A 5-second 768p clip is $0.375; 480p is $0.3125.

Perl still runs a lot of build glue, report generators and cron scripts, and none of it needs a video SDK. HTTP::Tiny and JSON::PP ship with Perl, and that is all the Sume video API needs: one POST, a poll loop and a GET for the finished file.
This post is the full script for MiniMax H3 (minimax-h3). It ran against a local stand-in server that returns the documented 202, poll and 302 shapes; the live service decides real render times. The script is 23 lines and uses HTTP::Tiny 0.076.
The script
Export SUME_API_KEY and run perl video.pl. The clip is 5 seconds at 768p, 16:9. 768p is H3's native size, so do not request 720p; the API would reject it.
use strict; use warnings;
use HTTP::Tiny; use JSON::PP qw(encode_json decode_json);
my $base = $ENV{SUME_API_BASE} // 'https://api.sume.com';
my $key = $ENV{SUME_API_KEY} // die "set SUME_API_KEY\n";
my $http = HTTP::Tiny->new(default_headers => { Authorization => "Bearer $key" });
my $res = $http->post("$base/v1/videos", {
headers => { 'Content-Type' => 'application/json', 'Idempotency-Key' => 'perl-h3-0001' },
content => encode_json({ model => 'minimax-h3', prompt => 'A koi pond at dawn',
duration => 5, resolution => '768p', aspect_ratio => '16:9' }),
});
die "submit failed: $res->{status} $res->{content}\n" unless $res->{status} == 202;
my $poll = decode_json($res->{content})->{polling_url};
while (1) {
sleep($ENV{POLL_SECONDS} // 30);
my $job = decode_json($http->get($poll)->{content});
die "$job->{status}\n" if $job->{status} =~ /^(failed|cancelled)$/;
next unless $job->{status} eq 'completed';
my $file = $http->get($job->{unsigned_urls}[0]); # HTTP::Tiny follows the 302
die "download failed: $file->{status}\n" unless $file->{success};
open my $fh, '>:raw', 'out.mp4' or die $!;
print $fh $file->{content}; close $fh;
print "cost $job->{usage}{cost}\n"; last;
}Notes on the code
Perl details first, then the API details.
HTTP::Tinyfollows redirects for GET by default, so the content URL's 302 needs no handling. The script checks$file->{success}so an error body is not written intoout.mp4.- The status check
dies onfailedandcancelled. A Perllastleaves the loop oncecompletedis saved. Idempotency-Keymakes a retried POST return the original job. Pick one key per clip you mean to create.- H3 always has native stereo audio, so the script does not send
generate_audio.
What it costs
MiniMax H3 is priced per second by resolution. Sume's price is the provider list rate times 1.25. The native sizes are 480p and 768p; 2K and 4K are paid upscales of the 768p picture, and text-to-video accepts 5 to 15 seconds.
| Resolution | Per second | 5 s clip | 15 s clip |
|---|---|---|---|
| 480p | $0.0625 | $0.3125 | $0.9375 |
| 768p | $0.075 | $0.375 | $1.125 |
References have a fee
Reference-to-video takes up to 9 images, 3 videos and 3 audio files, 12 in total. The first five reference images are free; each one after that adds $0.10 on Sume, which is the $0.08 list fee times 1.25. Plan a character sheet with five images or fewer if you want the per-second price to be the whole price. A 5-second 768p clip with seven reference images, for example, is $0.375 for the seconds plus two extra images at $0.10, which comes to $0.575. Checking that sum before you submit is cheap, and the reserve at submit is computed the same way, so an unexpectedly high reserve is a hint that you attached more images than you meant to.
Sources
Related posts
More in Developers
- PHP cURL: save a Sume-generated image to disk with CURLOPT_FILE
Two cURL calls in plain PHP: POST to /v1/images, read data[0].url on a 200, then stream the file to disk with CURLOPT_FILE. Handles 202 and a missing key.
- PHP cURL: submit a Seedance 2.5 video job, poll it, save the MP4
PHP with only ext-curl: POST /v1/videos for seedance-2.5, poll polling_url until completed, then download content?index=0; a 5-second 480p test costs $1.34.
- Pick a Sume video model by script: filter /v1/videos/models
Instead of guessing, call GET /v1/videos/models and filter by ratio, resolution and last frame. A 15-line Python script lists the Sume video models that fit.
- Pick an image model by capability from the Sume catalog in Python
Filter GET /v1/images/models by reference count, ratio and resolution tier instead of hard-coding ids. A short Python function that runs as written.
Written by Sume