PHP: submit a 30-second Wan 3.0 clip, poll it, save the MP4
Plain PHP 8 with curl and no SDK: send a 30-second wan-3.0 request, poll the job, and write the MP4 to disk. The 720p run is reserved at $3.75.

You can drive a 30-second Wan 3.0 clip from plain PHP 8 with curl: POST to /v1/videos with "model": "wan-3.0" and "duration": 30, poll GET /v1/videos/{id} until the status is completed, then save /content?index=0. At 720p Sume reserves $3.75 for the job. Alibaba lists wan3.0-video at 2 to 30 seconds and 30 fps MP4 (read 2026-10-08), and the Video generation docs give the same 2 to 30 second range for the wan-3.0 id.
The script
One helper does every call. CURLOPT_FAILONERROR turns any HTTP 4xx or 5xx into a failed request, so a 402 insufficient_credits stops the script instead of being parsed as a job.
<?php
$base = "https://api.sume.com";
$key = getenv("SUME_API_KEY") ?: exit("SUME_API_KEY is empty\n");
function sume(string $method, string $url, string $key, ?array $body = null, string $idem = ""): string {
$headers = ["Authorization: Bearer $key", "Content-Type: application/json"];
if ($idem !== "") $headers[] = "Idempotency-Key: $idem";
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_CUSTOMREQUEST => $method, CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true, CURLOPT_FAILONERROR => true]);
if ($body !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
$out = curl_exec($ch);
if ($out === false) exit("request failed: " . curl_error($ch) . "\n");
return $out;
}
$job = json_decode(sume("POST", "$base/v1/videos", $key, [
"model" => "wan-3.0", "prompt" => "A fishing boat leaving a harbor at dawn",
"duration" => 30, "resolution" => "720p", "aspect_ratio" => "16:9",
], "wan-php-001"), true);
do {
sleep(5);
$s = json_decode(sume("GET", "$base/v1/videos/{$job['id']}", $key), true);
} while (in_array($s["status"], ["pending", "in_progress"], true));
if ($s["status"] !== "completed") exit("ended as {$s['status']}\n");
file_put_contents("clip.mp4", sume("GET", "$base/v1/videos/{$job['id']}/content?index=0", $key));What each piece is for
Idempotency-Keyon the POST only: a retry of the same key returns the original job instead of a second charge. Change the key for a different request.durationis an integer. Send30, not30.0or"30s".- The poll loop treats
pendingandin_progressas running and everything else as terminal;failedandcancelledfall through to the exit message.
Price before you run it
The reserve is flat per second, so the whole table is known before you send anything.
| Resolution | Per second | 30-second clip |
|---|---|---|
| 480p | $0.0625 | $1.875 |
| 720p | $0.125 | $3.75 |
| 1080p | $0.25 | $7.50 |
Failure cases to handle
Three responses matter for a paid submit.
402 insufficient_credits: the balance cannot cover the reserve. Submit a cheaper request, or change plan, then retry with a fresh key if the request changed.409 idempotency_conflict: the key was used for a different payload. Mint a new key for a genuinely new request.429: the workspace has no accepted-job capacity right now. Wait, then retry with the same key; the Generation admission page lists the codes.
Before production
Replace the five-second sleep with a callback_url if the script runs under a web request limit; the callback must be HTTPS. Keep the key in the environment, never in the file, and log the job id next to the prompt so a cost line can be traced to its request.
Sources
Related posts
More in Developers
- Pick one of four: an n=4 call costs $0.60 or $0.22 on Sume at 2K
A call with n=4 at 2K costs $0.60 on Nano Banana 2.1 or $0.22 on GPT Image 2.5 medium on Sume, because Sume bills cost_usd times n. See the table.
- Pick the cheapest Video Router model from the live catalog
Read GET /v1/video-router/models, filter by resolution, duration and capability, and rank by list x 1.25 in integer micros. Node code with an offline test.
- Pin Gemini Omni Flash 1.1 or send sume/auto: six checks
sume/auto picks the model for video and defaults to 720p and 8 s. Pin gemini-omni-flash-1.1 when you need edit mode, 4K or fixed references. A decision table.
- Pinterest video aspect ratio text, quoted, and a master check
Pinterest's video spec says 'shorter than 1:2, taller than 1.91:1'. Quote it, convert the recommended ratios to decimals, and check a master with Sume frames.
Written by Sume